pi-simple-skills-manager1.0.0
A pi extension for exposing reviewed skills to the model: a single JSONC config file holds every library root (the registrar) and approved skill manifest, /skills-manager manages everything interactively in a tree navigator, skills are hash-bound and fail
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-simple-skills-manager
A pi extension for exposing reviewed skills to the model — with a scan-approval workflow, content hashes that fail closed on drift, a tree navigator for the whole library, and an honest mirror of pi's own native skill discovery.
One file, one command. Everything — library roots (the registrar),
approved skill manifests, and extension settings — lives in
~/.pi/agent/pi-simple-skills-manager.json, and everything is manageable from
the /skills-manager TUI. Skills themselves are plain files: the built-in
store accumulates them at ~/.pi/agent/managed-skills, and existing or
native directories are adopted without moving anything.
Why this exists
pi already has native skills: drop a folder in ~/.agents/skills/ and pi
exposes it. Native discovery has zero ceremony — which is exactly the
point of divergence. A skill is untrusted instructions the model will
follow, plus scripts it may execute, with your user permissions. Native
pi's answer to "is this skill safe to expose?" is "it's on your disk, so
yes."
"A skill is on your disk" never silently means "the model follows it." This extension keeps three decisions separate, on purpose:
- Configuration — where a root is and how the library is scanned.
- Manifest approval — which skill names, descriptions, and content hashes a human actually inspected, fingerprinted to the exact root.
- Invocation — whether the model may load a particular skill right now.
If you wrote every skill yourself and trust your own directories, native pi is fine — this extension is opt-in governance for when the collection grows, comes from third parties (Anthropic skills, pi-skills, Claude/Codex imports), or you simply want to see and control what every chat is being influenced by.
What it adds over native pi skills
| Native pi skills | pi-simple-skills-manager | |
|---|---|---|
| Exposure gate | On disk → in every chat's system prompt at next startup. Zero ceremony. | Scan → approve (fingerprint-bound) → expose. |
| Content drift | Silent. | Hash-bound approval; changed content fails closed at invocation until re-approved. |
| Per-skill control | Minimal (frontmatter flag). | Tree navigator with spacebar exposure checkboxes, enable/disable, live state. |
| Management UI | None. | /skills-manager: grouped tree, rendered skill view, metadata (hash, file inventory, executable-script warnings), edit-in-place, remove, imports. |
| Invocation | /skill:name (user), read-on-demand (model). |
Same /skill:name syntax (shadowed, drift-checked) plus namespaced tools the model calls; live autocomplete dropdown carries group paths. |
| Delivery hygiene | Raw file content. | Sanitized, bounded, collision-checked names (skill_<root>__<skill>), harness awareness lines. |
| Laziness | Frontmatter read for every chat at startup. | The root is not scanned until an approved skill is invoked. |
Quick start
Inside pi:
- Run
/skills-manager— a starter config and the store (~/.pi/agent/managed-skills) are created on first run. - Add a skill to the store: write one in the editor, import an
.mdfile, or import a whole directory (if it has noSKILL.md, the TUI prints its tree and asks which one it is). - Or Add or import a library root: point at any skills directory or a single skill. Native pi locations need no adding — they appear automatically when they exist.
- The scan ceremony shows exactly what was found — descriptions, file counts, executable-script warnings, rejections — and asks which skills to expose.
- Reload. Exposed skills appear as
skill_<root>__<skill>tools for the model andskill:<name>commands for you.
Groups
Subdirectories of the store are groups — "subdirs as automatic tagging."
managed-skills/research/arxiv/SKILL.md displays as research / arxiv in
the tree; move the directory and it re-tags on the next scan. No group
config exists anywhere.
The tree navigator
/skills-manager → Open the library tree: every root sits flat at the
top level (store first, auto-detected native roots included), groups nest
beneath, skills are leaves with [√]/[ ] checkboxes. Spacebar toggles
exposure; unchecked means invisible to the model. Enter inspects (metadata,
live drift check, full content, edit/remove for store skills; on roots:
overview plus bulk enable/disable, scan-or-refresh, and remove actions).
Red ⊘ leaves are native mirrors — skills pi is exposing through its own
discovery that cannot be revoked here; the footer explains how (remove the
files, or launch pi --no-skills).
Native roots and the override story
- Auto-adoption.
~/.pi/agent/skillsand~/.agents/skillsare recognized automatically: if they exist on disk, they appear in the registrar on the next load — disabled, unapproved, flagged "Auto-detected" — showing their natively-live skills as red unscanned leaves. Scan or refresh is the adoption ceremony. Auto-adoption never creates exposure: nothing is enabled, approved, or even scanned without an explicit act. - Command layer — fully ours. Every exposed skill registers a
skill:<name>extension command; extension commands dispatch before pi's native skill expansion, so the namespace is shadowed, with drift checking pi doesn't have. The live autocomplete dropdown narrows as you type, withgroup/skillpaths in the descriptions. - Discovery layer — not overrideable by an extension. If files sit in
~/.pi/agent/skills/or~/.agents/skills/, pi will list them in the system prompt. The manager is the honest mirror: auto-detected roots render their skills red and locked in the tree, drift-checked on our surfaces, with unapproved-but-live skills visible. - Library-only mode — the full takeover: launch
pi --no-skillsand native discovery stops entirely. The mirror rule finds nothing, native roots become fully gated, and the manager is the sole skills surface. (The extension detects and displays which mode is live in the tree footer.)
Security model
Skills instruct the model and may include code it executes with your permissions. Permission prompts are not an OS sandbox. This extension's boundaries:
- scanning is read-only and bounded (file counts, depth, per-file sizes);
- symlinks fail closed (roots and skills); nothing is ever executed;
- exposure requires an approved manifest, and every invocation re-hashes the bytes being delivered against the approval — drift fails closed;
- the manifest fingerprint binds the approval to the exact root (name/transport/path) — move it and the approval is void;
- helper scripts are inventoried and shebang files flagged at inspection (their content is not hash-bound; re-scan before trusting — same posture as an MCP server whose code may change under bound schemas);
- skill text is sanitized and size-bounded on delivery;
- external and native roots are read-only to the manager; store deletions
are constrained to
managed-skills/; - hidden skills (
disable-model-invocation) are command-only, mirroring pi's semantics.
Review skill content; pin or vendor third-party skills; use a container or VM when you need real isolation.
Testing
No external model or untrusted network calls — local fixtures only:
npm run typecheck # tsc --noEmit
npm test # tests/smoke.sh
The smoke test exercises both transports end-to-end (discovery, grouping,
script flagging, rejections), validation invariants, config save/load
round-trips (upsert, remove, settings fallback, loud failure on a corrupt
file), manifest fingerprint binding, the full registered-tool execute path
(lazy scan at first call, reuse, fail-closed content drift), managed
discovery through pi's normal extension loading (per-entry isolation,
lazy registration against a nonexistent directory, native-tool
preservation, skill:<name> command registration), native mirror
computation, and first-run starter creation. Dedicated regression suites
cover the registered-name length invariant, defensive handling of a
malformed approved manifest, scan-budget and maxSkills enforcement,
pathological-source survival, copy-budget and snapshot file-name
invariants, and tree resilience against an unresolvable root-path
template — each verified to fail against the exact bug it guards.