Skip to content

Rebuild the defaults

Your first extension worked. /stash re-extracts a saved URL on command, and the custom tool behind it does exactly what you told it to. You’ve proven to yourself that Pi’s four-tool core plus a little TypeScript can grow into whatever stash needs. Which is exactly when a less comfortable thought shows up: what’s stopping it from growing into something you didn’t ask for?

Nothing. That’s not a bug you missed - it’s the whole design. Pi ships with no permission-prompt gate at all. No sandbox, no allow/ask/deny list, no confirmation before a bash call. Every tool call that reaches the model runs, full stop. Pi calls this out plainly rather than burying it: the design position is that most permission-prompting is security theater, and that allow-listing individual commands doesn’t scale, so Pi doesn’t bother shipping any of it. That’s a real, considered position - not an oversight - and it’s worth sitting with before you reach for the fix. But stash is no longer a toy repo you’re poking at. It’s holding real state now: a SQLite database with every article you’ve saved, and a .env file carrying the tokens the fetch worker and search index need to do their jobs. An agent with unrestricted bash and write access is one confidently-wrong turn away from rm-ing the database or catting a secret into a commit message. You want the same leash other tools bolt on by default - you just want to have built it yourself, so you know exactly what it does and doesn’t cover.

That’s this module. Three things Pi deliberately left out, plus one default worth replacing rather than accepting as-is, all rebuilt as extensions on the exact hooks you’ve already been using since Module 5 - and in each case, understanding why Pi shipped it the way it did is as important as the code that adds to or replaces it:

  • Permissions - a damage-control extension that reads a rule file and gates every tool_call: some violations stop you outright, some let the agent adapt and keep moving. The YOLO-by-default reality, and what it means to accept it deliberately instead of by accident.
  • Task discipline - Pi has no to-do list, on the view that structured task tracking confuses models more than it helps. You’ll build a stricter version anyway: a gate that blocks every other tool until exactly one task is in progress, with state rebuilt from session history instead of a side file.
  • Plan mode - Pi has no dedicated planning posture at all. In its place: a PLAN.md habit that persists across sessions and stays fully readable, on the same hook you’ll recognize from the permission gate.
  • Statusline - Pi’s default footer already shows model, context percentage, and cost; you’ll replace it with one that also tracks a live tool tally, built from the same footer contract every other statusline extension in the wild reuses.

None of this makes Pi into Claude Code or Codex with a different paint job. It makes the guardrails a set of files you own, can diff, and can turn off the instant they get in your way - which is the trade Pi is actually offering you, not the one you assumed it was offering before you read the fine print.

Start with the sharpest of the four: stopping the agent from deleting the thing you can’t get back.