Skills and Extensions I built for Pi Agent
Skills and Extensions I built for Pi Agent
When I started using a local llm my focus was primarily to use it to reduce costs of my use of claude. That meant that I wanted to pick a harness that would be lightweight and flexible. I had heard of Pi and open code and after looking over the two briefly decided that Pi aligned more with my interests. Plus I wanted to explore "building my own" harness, so picking a lightweight and extensible system made a lot of sense to me. I've built a handful of extensions and skills (with the help of Claude and Pi) to make Pi more successful in the work I give it. First I'll work through the extensions I've built for Pi and then the skills I've built for both Claude and Pi. I went into this to save on my Claude usage, but that turned out not to be the most interesting part. With this hybrid system I am seeing better results than just with Claude alone.
Everything in this post is on github at corporealshift/pi-extensions if you want to read the source or use any of it yourself.
Pi Extensions
I wanted my Pi agent to have some of the same kinds of things that Claude Code has. To get started on this project, I asked Claude "what are the tools you have that pi doesn't have, and help me build them." That got me started and I selected the tools I thought were most relevant to me and then gave Claude some direction on how I wanted them to work. Here are some of the things I've had it and Claude build to make the development process nicer.
Bash Guard
This one is pretty straightforward, it just prevents pi from running dangerous bash commands, like rm -rf or git force push. It works by using pi's tool_call hook and a simple regular expression, and then either prompts the user (in interactive mode) or denies the call. Simple but (in theory, I haven't seen this get invoked yet) effective prevention against weird "LLM is stuck" failures. While the name is "bash guard" it also has protections against powershell commands.
Checkpoints
Another tool_call hook, this extension saves a snapshot of a file prior to applying edits to it. This lets me easily undo edits that Pi has made to my files if/when it mangles something, or I decide not to keep a change. This is handled separate from Git, so changes can be unwound even if Pi went crazy and mangled the Git tree.
Lint Gate
This is one of my favorites! It prevents Pi from declaring work is complete without running the lint checks for a project. I have it set up to not do anything unless a configuration file exists, but when one does it uses the turn_end hook to run the project's check command, and tells Pi to fix any issues that arise.
turn_end looks like the wrong hook
I was looking at this extension for this blog post and discovered that agent_end is the hook it should use - my hooks extension already listens on it. I'll have to explore making that change at some point.
Memory
Does what it sounds like. Gives Pi the ability to store memories in the ~/.pi/memory directory. Uses an index file (MEMORY.md) with pointers to all other memories.
Ask User
This gives Pi the ability to ask a user questions with multiple choice answers. It's an essential part of any discovery or exploration type work. Otherwise, Pi will often make assumptions about what I want when I am unclear. In non interactive mode (i.e. when Claude triggers it) it will proceed with its assumption and state the assumption.
Plan Mode
Puts Pi into plan mode, which blocks creating or editing files with a tool_call hook. Pi is extremely eager to just do work, so this extension can really help when you really don't want it to start doing things.
Spec Progress
This tool writes Pi's progress on a current spec into a markdown file in the project's .pi/specs directory. I wanted this because my Pi can get interrupted by me wanting to use my computer for other things like playing games, and I found it struggled to restart tasks.
BG Tools
Lets Pi start tasks in the background so it can continue to do other things while it waits for a command to complete.
Task Manager
This is a to-do list tool. Pi can create its own to-do list, check off these items, and presents the status of the tasks in the Pi TUI. This seems to help Pi get work done and keep it on task even through context compaction events. It's also nice to see it check off work as it completes it.
Forking Superpowers
I am a big fan of the Superpowers skill set. They do a great job of helping Claude get work done without getting too much in the way. By default the skills are designed to delegate work to sub agents, but Claude will just pick one of its own models to accomplish the task. I wanted to have this same workflow, but I wanted Pi to be my subagent, which required changing the superpower skills. At first I just slotted Pi in as the sub agent for coding, which Claude invokes via the normal subagent flow. Eventually I expanded Pi's use here to writing plans and specs, which seems to work nicely.
In order to get Claude to work nicely with Pi I had to adjust some of the expectations - Pi is slow, so normal waiting mechanisms in Claude Code tend to fail prior to Pi completing a task, and Claude is very pessimistic of Pi's ability to do anything. Claude would often "give up" on Pi and just decide to do the work itself, which defeats the point of this hybrid setup. The skills below help Pi accomplish some specific tasks and help Claude manage its expectations for how Pi works.
One unexpected thing I've noticed - I feel like I get better results with the hybrid process! I believe this is because Claude is more skeptical of other agents' output so it reviews it more thoroughly. This cross-system "prove what you say" approach seems to apply in code, tests, and planning as well. I have now also incorporated this into my prompts with Claude about why we use Pi, and that has also seemed to help improve results.
Claude really doesn't want to delegate
I'm not sure what it is exactly, but Claude really doesn't want to delegate work to another system. For example, one time I killed a Pi process mid stream so I could play a game. Claude immediately wanted to write to its memory that Pi is unreliable and to only delegate simple tasks.
Once I had the skills customized to this workflow, things more or less "just worked." I can ask Claude to do work and Claude will delegate implementation to Pi via the pi command.
Specialized Skills
In order to optimize this new approach I built some skills for Pi and Claude. These help each other work seamlessly together on tasks and have tables of "common failures" to help overcome some of the challenges that each has.
Pi: Brainstorming
This is just a copy of the brainstorming skill from superpowers, but I just wanted to be able to have Pi be able to use it too.
Pi: Writing Plans
This is the biggest change. Pi now has its own skill for how to write plans, tailored to the expectations that Claude has and to guard against specific common gotchas that Pi has introduced when planning work. I've mostly just let Claude make these adjustments as it sees fit, and it seems to be working well.
Claude: Delegating to Pi
I have also created a dedicated skill that helps Claude know how to delegate to Pi. It covers when to use Pi, how to invoke the delegation, and how to actually track when Pi is done, since the Claude run command tool will time out before Pi finishes work. This was really frustrating at first - Claude would say Pi "died" when it had not, and then they would both try to work on the project and spend tons of tokens stepping on each other. Getting Claude a clear way to know when Pi is done working was a fundamental requirement to getting this system to work.
Conclusions
It has been a lot of fun getting Claude and Pi to work together. Building my own harness extensions has been fun and enjoyable too - Of course, I just ask Claude to build it for me, but it's still fun to think about how the system should work and what improvements to make. At this point I can either interact with Pi directly and let it loose on something, or have Claude work in this hybrid setup, or let Claude loose on a project on its own. For the last one, it's as simple as just telling Claude not to use Pi right now, and it handles that nicely.
The part that surprised me the most is the quality thing I mentioned earlier. I set all of this up to stretch my Claude usage further, and it does, but I was delighted to see this extra advantage. Handing work to a different system provides a review step that just doesn't happen when Claude checks its own output. Claude reads Pi's code expecting to find problems, and it usually finds some.
I hope that my overview of these extensions gives you some ideas for your own setup! Of course there are publicly available extensions for a lot of this work, but I wanted to truly "DIY" my setup. If you're not interested in doing that, the plugins catalog is really great.