♠ Previously, previously.
Problem statement: adopt caveman in pi.
Pi isn’t one of the 30+ agents caveman auto-detects. The install matrix
(INSTALL.md
) lists agent detection rules one by one — claude
, cursor
,
windsurf
, opencode
, openclaw
, etc — and pi isn’t in it. Running the one-liner installer here would just skip everything silently. Booo!
Rather than run someone else’s curl | bash
against an agent it wasn’t built
for, “““I””” reimplemented the terse-speak part natively, since pi
already ships the two primitives needed: skills and extensions.
A
skill
for /skill:caveman
documentation, and an extension that rewrites the system
prompt on every turn via pi.on("before_agent_start", (event) => ...)
:
const INSTRUCTIONS = `Caveman mode: on. Respond terse. Drop articles (a/an/the), filler (just/really/basically), pleasantries, hedging. Fragments OK. Short synonyms. Technical terms exact. Pattern: [thing] [action] [reason]. [next step]. Example — not: "Sure! I'd be happy to help you with that." yes: "Bug in auth middleware. Fix:"
Boundaries, always: code blocks, commit messages, and PR descriptions stay normal full verbosity, never compressed. Drop caveman style for security warnings, irreversible/destructive actions, or when the user seems confused — resume caveman after.`;
export default function (pi: ExtensionAPI) {
let on = true; // auto-on by default, every session
const applyStatus = (ctx: { ui: { setStatus: (k: string, v?: string) => void } }) => {
ctx.ui.setStatus("caveman", on ? "[caveman]" : undefined);
};
pi.on("session_start", async (_event, ctx) => applyStatus(ctx));
pi.on("before_agent_start", (event) => {
if (!on) return;
return { systemPrompt: `${event.systemPrompt}\n\n${INSTRUCTIONS}` };
});
pi.registerCommand("caveman", {
description: "Toggle caveman terse-response mode: on|off (default: on)",
handler: async (args, ctx) => {
const arg = args.trim().toLowerCase();
if (arg === "off" || arg === "stop" || arg === "normal") on = false;
else if (arg === "on" || arg === "") on = true;
else return ctx.ui.notify(`Unknown arg "${arg}". Use: on | off`, "error");
applyStatus(ctx);
ctx.ui.notify(on ? "Caveman mode on." : "Caveman mode off.", "info");
},
});
}
before_agent_start fires on
~/.pi/agent/extensions/caveman.ts
, auto-discovered, no /reload
needed after
the first load.Unlike the Claude Code plugin, I skipped lite
/full
/ultra
/wenyan
— I called that bloat back in June, and I’m not adding it to my own version either. On or off is enough.
The result, unprompted:
user: caveman on or off now?
assistant: Caveman: on.
user: how to turn it off?
assistant:/caveman off
I also skipped the parts that don’t have a pi equivalent: the statusline
savings counter, /caveman-stats
, the caveman-shrink
MCP proxy that rewrites tool descriptions (a proxy that rewrites what an agent sees is exactly the kind of thing worth reading before installing). The 40-line extension above covers what I actually wanted.
One rule baked into both the skill and the extension: code, commits, and PRs stay full verbosity, never compressed.
This experience was an eye-opener for me to realize how bloated the upstream caveman project became.
🤖 *Drafted with *
/bloggify
.— § —
Reply via [email](mailto:serendipity@perrotta.dev?subject=Reply to: pi: caveman mode)