Files
ponytail/pi-extension/index.js
T
92efc4a648 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>
2026-06-14 17:35:45 +02:00

147 lines
4.7 KiB
JavaScript

import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const {
DEFAULT_MODE,
getDefaultMode,
normalizeMode,
normalizeConfigMode,
normalizePersistedMode,
writeDefaultMode,
} = require("../hooks/ponytail-config.js");
const { getPonytailInstructions, filterSkillBodyForMode } = require("../hooks/ponytail-instructions.js");
export { filterSkillBodyForMode };
export const readDefaultMode = getDefaultMode;
export function resolveSessionMode(entries, fallbackMode = DEFAULT_MODE) {
const fallback = normalizePersistedMode(fallbackMode) || DEFAULT_MODE;
if (!Array.isArray(entries)) return fallback;
for (let i = entries.length - 1; i >= 0; i -= 1) {
const entry = entries[i];
if (entry?.type !== "custom" || entry?.customType !== "ponytail-mode") continue;
const mode = normalizePersistedMode(entry?.data?.mode);
if (mode) return mode;
}
return fallback;
}
export function parsePonytailCommand(text, defaultMode = DEFAULT_MODE) {
const fallback = normalizePersistedMode(defaultMode) || DEFAULT_MODE;
const normalizedText = String(text || "").trim().toLowerCase();
if (!normalizedText) {
return { type: "set-mode", mode: fallback === "off" ? "full" : fallback };
}
const [primary, secondary] = normalizedText.split(/\s+/);
if (primary === "status") return { type: "status" };
if (primary === "default") {
const mode = normalizeConfigMode(secondary);
return mode ? { type: "set-default", mode } : { type: "invalid", reason: "invalid-default-mode" };
}
const mode = normalizeMode(primary);
return mode ? { type: "set-mode", mode } : { type: "invalid", reason: "invalid-mode", mode: primary };
}
export { writeDefaultMode };
export default function ponytailExtension(pi) {
let currentMode = DEFAULT_MODE;
let configuredDefaultMode = getDefaultMode();
const setMode = (mode, ctx) => {
const normalized = normalizePersistedMode(mode);
if (!normalized) return;
currentMode = normalized;
pi.appendEntry("ponytail-mode", { mode: normalized });
ctx?.ui?.notify?.(`Ponytail mode set to ${normalized}.`, "info");
};
const sendAlias = (skillName, args, ctx) => {
const normalized = String(args || "").trim();
const message = normalized ? `${skillName} ${normalized}` : skillName;
if (ctx?.isIdle?.() === false) {
pi.sendUserMessage(message, { deliverAs: "followUp" });
ctx?.ui?.notify?.(`${skillName} queued as follow-up.`, "info");
return;
}
pi.sendUserMessage(message);
};
pi.registerCommand("ponytail", {
description: "Set or report Ponytail mode",
handler: async (args, ctx) => {
const parsed = parsePonytailCommand(args, configuredDefaultMode);
if (parsed.type === "status") {
ctx?.ui?.notify?.(`Ponytail: current ${currentMode} • default ${configuredDefaultMode}`, "info");
return;
}
if (parsed.type === "set-default") {
const written = writeDefaultMode(parsed.mode);
if (written) {
configuredDefaultMode = getDefaultMode();
const message = configuredDefaultMode === written
? `Default Ponytail mode set to ${written}.`
: `Saved default ${written}, but env override keeps default at ${configuredDefaultMode}.`;
ctx?.ui?.notify?.(message, "info");
}
return;
}
if (parsed.type === "set-mode") {
setMode(parsed.mode, ctx);
return;
}
ctx?.ui?.notify?.("Unknown or unsupported /ponytail mode.", "warning");
},
});
pi.registerCommand("ponytail-review", {
description: "Run /skill:ponytail-review",
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", {
description: "Run /skill:ponytail-help",
handler: (_args, ctx) => sendAlias("/skill:ponytail-help", "", ctx),
});
pi.on("input", async (event) => {
if (event?.source === "extension") return;
const text = String(event?.text || "");
if (currentMode !== "off" && /\b(stop ponytail|normal mode)\b/i.test(text)) {
setMode("off");
}
});
pi.on("session_start", async (_event, ctx) => {
const entries = ctx?.sessionManager?.getBranch?.() || ctx?.sessionManager?.getEntries?.() || [];
configuredDefaultMode = getDefaultMode();
currentMode = resolveSessionMode(entries, configuredDefaultMode);
});
pi.on("before_agent_start", async (event) => {
if (!currentMode || currentMode === "off") return;
return { systemPrompt: `${event.systemPrompt}\n\n${getPonytailInstructions(currentMode)}` };
});
}