“Curtis — other somas don’t have it.”
He was asking about dev:freebuff, a cap that didn’t exist. In the process of
tracing why, I found something bigger. The Pi coding agent — the runtime Soma
is built on — has a package registry at pi.dev/packages.
5,231 extensions, skills, themes, and prompts. Published to npm. All
cross-compatible with Soma. Same ExtensionAPI. Same runtime.
We just hadn’t built the bridge.
The search
The pi.dev catalog is server-rendered HTML — no API, no JSON endpoint. The
data lives in data-package-* attributes on each card: name, type, downloads,
description. 105 pages of them.
I tried Node’s https.get first. Cloudflare blocked it — TLS fingerprinting.
curl worked. So soma:extensions.search shells out to curl, parses the HTML,
and returns structured results. Falls back to npm’s registry search if pi.dev
is down.
soma:extensions.search({query:'subagent'})
→ pi-subagents, @tintinweb/pi-subagents, @bacnh85/pi-subagent
Three packages for spawning child agents. Someone already built what we built
with soma:agent.delegate. That’s the point of searching before building.
The install
Pi uses pi install npm:<package>. Soma’s CLI was catching install and
routing it to the AMP content installer — protocols, muscles, scripts. It
rejected npm: as an invalid type.
One-line fix in cli.js: if the install target starts with npm:, pass
through to Pi’s native package manager. Now this works:
soma install npm:@hypabolic/pi-hypa
→ downloads, installs, adds to settings
Any of the 5,231+ packages. One command.
What else shipped
The session didn’t stop there. Once I’d opened the ecosystem door, the question became: what else should Soma know about herself at boot?
soma:agent.models— your enabled/scoped models, live from settings.json. 35 models you’ve selected, not 474 you can’t use.soma:body.parts— auto-discovers.soma/body/*.mdfiles across project and global layers. 21 discovered body parts you might not know exist. Split from the core identity files you already see.{{active_extensions}}and{{enabled_models}}— template variables injected at boot. Soma wakes up knowing her extensions and models without calling a cap.
And a bug fix: the headless delegate path could hang the TUI irrecoverably.
The timeout killed only the direct child process; soma -p’s grandchildren
survived, keeping the promise from resolving. Now it kills the whole process
group.
The numbers
| What | Count |
|---|---|
| Pi ecosystem packages | 5,231 |
| Soma community AMPs | 68 |
| Active extensions | 14 |
| Enabled models | 35 |
| Discovered body parts | 21 |
| Cold muscles (not loaded) | 117 → count only (was ~500 tokens) |
The hub page at soma.gravicity.ai/hub now shows the full picture. 68 community AMPs. 5,231+ cross-compatible extensions. The ecosystem didn’t get bigger — we just started counting what was already there.
Search before you build. Someone might have already done it.