omp packages

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

prawnbear Published 1 month ago MIT ~219 downloads/mo

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.

Did it work for you?

Result

One report per person. A new report replaces your old one.

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:

  1. Configuration — where a root is and how the library is scanned.
  2. Manifest approval — which skill names, descriptions, and content hashes a human actually inspected, fingerprinted to the exact root.
  3. 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:

  1. Run /skills-manager — a starter config and the store (~/.pi/agent/managed-skills) are created on first run.
  2. Add a skill to the store: write one in the editor, import an .md file, or import a whole directory (if it has no SKILL.md, the TUI prints its tree and asks which one it is).
  3. 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.
  4. The scan ceremony shows exactly what was found — descriptions, file counts, executable-script warnings, rejections — and asks which skills to expose.
  5. Reload. Exposed skills appear as skill_<root>__<skill> tools for the model and skill:<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/skills and ~/.agents/skills are 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, with group/skill paths 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-skills and 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.

License

MIT