Back to blog
·2 min read·Pi / Developer Tools / TypeScript

Building Pi extensions that get out of the way

Notes from shipping pi-tool-display, pi-rtk-optimizer, and pi-permission-system - what I learned about writing terminal extensions that disappear into the workflow.

Building Pi extensions that get out of the way

The best Pi extensions feel like they were always there.

After shipping a handful of them - tool-display, rtk-optimizer, permission-system, sensitive-guard - the pattern that keeps showing up is that the extensions people actually keep installed are the ones that disappear into the workflow. They don't add UI. They don't ask for attention. They just quietly fix something that was annoying yesterday.

The selection rule I keep going back to

Before adding anything, I ask whether it makes a session shorter, quieter, or safer. If the answer is no, the extension is probably feature-creep. Tool-display compacts verbose output, so sessions are shorter to read. RTK-optimizer rewrites noisy commands, so sessions are quieter. Permission-system blocks dangerous tool calls, so sessions are safer. The rule narrows the field in a useful way.

Trust over cleverness

Every extension I ship sits between the agent and the user. That position is unforgiving. If the extension hides something the user needed, they'll lose trust fast and uninstall. So the engineering bias has to lean toward conservative defaults, predictable behavior, and clear escape hatches.

// Pattern I keep reaching for: opt-in transformations, never silent ones
if (config.compactDiffs && isLikelyDiff(output)) {
  return compactDiff(output)
}
return output

Boring code. But the boredom is the point. Predictability is the feature.

What I'd tell myself a year ago

Don't try to do too much in one extension. Each one I've shipped does a single thing. That makes them composable - users can mix and match - and it makes maintenance sane. The temptation to bundle features always loses to the discipline of keeping each project narrow.