@varnothing-works/pi-skill-families

Family-level skill manager for Pi: batch-toggle skill families and let the agent discover, enable, and reorganize disabled skills at runtime.

Packages

Package details

extension

Install @varnothing-works/pi-skill-families from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@varnothing-works/pi-skill-families
Package
@varnothing-works/pi-skill-families
Version
0.1.1
Published
Oct 21, 2026
Downloads
not available
Author
ken-zhang
License
MIT
Types
extension
Size
63.1 KB
Dependencies
0 dependencies · 3 peers
Pi manifest JSON
{
  "extensions": [
    "./src/extension.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-skill-families

Website · npm · GitHub

A Pi extension that manages skills by family. It keeps a large skill library on disk but only advertises the families and skills you want in the current session. The agent can inspect disabled skills, read them, enable them, and reorganize families at runtime.

This is an agent-facing tool. There is no /skills TUI or command; ask the agent to manage families in conversation.

The npm package is @varnothing-works/pi-skill-families. The model-facing tool is skill_families, matching Pi's snake_case tool names (tool_search, mcp__server__tool).

Why

Progressive disclosure keeps full skill bodies out of the prompt, but every installed skill still contributes its name and description. Large libraries have two costs:

  • Context: a few hundred skills can add tens of thousands of tokens to every request.
  • Selection: as libraries grow, agents increasingly pick the wrong skill ("skill shadowing"), even when the right one is present.

Families let you narrow the advertised set by topic without deleting skills or remembering to reinstall them later. Disabled skills remain discoverable through the skill_families tool.

Requirements

  • Pi 1.3.0. Tested with 1.3.0; the extension relies on before_agent_start system prompt options, registerTool, and withFileMutationQueue.
  • A session that discovers at least one skill from .agents/skills, .pi/skills, or a configured skill directory.

Install

From a local checkout (works without publishing):

pi -e /path/to/pi-skill-families
# add it to the current project:
pi install -l /path/to/pi-skill-families

From GitHub:

pi install git:github.com/varnothingworks/pi-skill-families

From npm:

pi install npm:@varnothing-works/pi-skill-families

pi -e loads the package for one run without changing settings.

Use

The examples below use the public sample families from docs/SAMPLE-DATA.md. Talk to the agent:

Disable the Docs family.
Split the Frontend skills into frontend-ui, frontend-react, and frontend-web.
Enable only vercel-react-best-practices from the Frontend family.
Show me which skills are disabled and why.
Move vercel-react-best-practices into frontend-web.

The agent calls skill_families with one of these actions. enable and disable update state immediately; the advertised skill list changes on the next turn. Use show when you need the instructions in the current turn.

Action Purpose
status Counts, family summary, disabled skills, pattern overlaps
families Family ids, names, patterns, and enabled counts
list List skills, filtered by family, name, status, or query
search Search names and descriptions, including disabled skills
show Read a skill's SKILL.md, even when disabled
enable / disable Toggle a skill or a whole family
reset Clear overrides; optionally reset one family
create_family Create a family with glob patterns and a position
update_family Change a family's name, patterns, or order
delete_family Delete a family; release or reassign explicit members
move_skill Move one skill to a family, or to uncategorized
unassign_skill Remove an explicit assignment so patterns apply again

list and search return each skill's name, effective state, family, and a 160-character description summary. Pass verbose: true to get full descriptions; use show for the complete SKILL.md. status and families return names and counts only.

Family creation, updates, and deletion support preview: true, which shows members and overlaps without writing anything.

Verify it works

Start Pi where skills are discoverable and ask the agent:

Call skill_families with action=status and show the first line.

A fresh install shows every discovered skill enabled, for example (the 35-skill public sample):

Skills: 35/35 enabled, 0 disabled.

If the count is zero, the session has no discovered skills. Start Pi from the workspace that contains .agents/skills.

How it works

On every turn, the extension filters event.systemPromptOptions.skills in before_agent_start. Only enabled skills reach the system prompt. A short summary tells the model which families are disabled and that skill_families can search or enable them.

State lives in two files at the workspace root:

.pi/skills-families.json   # family definitions and explicit assignments
.pi/skills-state.json      # family and per-skill toggles

The workspace root is the nearest ancestor with skills-lock.json or .agents/skills; otherwise the current directory. .pi/skills-families.json is created on the first family change; .pi/skills-state.json is created on the first toggle.

Precedence

per-skill setting > family setting > default

The default is enabled, so installing the extension does not change behavior. Disable a family, then enable individual exceptions as needed:

{
  "version": 1,
  "default": "enabled",
  "families": {
    "posthog": "disabled"
  },
  "skills": {
    "querying-posthog-data": "enabled"
  }
}

Family definitions

{
  "version": 1,
  "families": [
    {
      "id": "frontend-ui",
      "name": "Frontend UI",
      "patterns": ["frontend-ui-engineering", "web-design-guidelines"]
    },
    {
      "id": "frontend-react",
      "name": "Frontend React",
      "patterns": ["vercel-react-*", "vercel-composition-patterns"]
    },
    {
      "id": "frontend-web",
      "name": "Frontend Web",
      "patterns": ["frontend-design", "web-artifacts-builder"]
    }
  ],
  "assignments": {
    "vercel-react-best-practices": "frontend-web"
  }
}
  • Families are matched in order; the first match wins.
  • patterns use * for any characters and ? for one.
  • assignments are explicit and override patterns.
  • Unmatched skills fall into uncategorized.
  • move_skill to uncategorized pins a skill outside every family. unassign_skill releases it back to pattern matching.

Splitting a broad family

Ask the agent to do it, or use the same sequence with tool calls:

skill_families({ action: "list", family: "frontend" })
skill_families({ action: "create_family", id: "frontend-ui", display_name: "Frontend UI", patterns: ["frontend-ui-engineering", "web-design-guidelines"], position: 0, preview: true })
skill_families({ action: "create_family", id: "frontend-ui", display_name: "Frontend UI", patterns: ["frontend-ui-engineering", "web-design-guidelines"], position: 0 })
skill_families({ action: "create_family", id: "frontend-react", display_name: "Frontend React", patterns: ["vercel-react-*", "vercel-composition-patterns"], position: 0 })
skill_families({ action: "create_family", id: "frontend-web", display_name: "Frontend Web", patterns: ["frontend-design", "web-artifacts-builder"], position: 0 })
skill_families({ action: "move_skill", name: "vercel-react-best-practices", family: "frontend-web" })
skill_families({ action: "status" })

Create the remaining families, adjusting position if patterns overlap. Use move_skill for skills that patterns cannot capture.

Limitations

  • The manager only sees skills discovered in the current session. Starting Pi inside a project repository stops .agents/skills discovery at that repository root, so workspace skills are not visible there.
  • Disabling a skill removes it from the advertised list; it is not access control. The model can still read a file if it knows the path.
  • Skill content already read into the conversation remains in history after disabling.
  • Toggling skills changes the system prompt between turns, which can invalidate prompt caching. Changes are infrequent.
  • Existing disable-model-invocation skills keep that behavior; the manager does not override it.

Development

npm install
npm run check      # typecheck + tests

Tests cover pattern precedence, family CRUD, explicit assignments, prompt filtering, previews, and state resets. The extension is loaded directly from TypeScript via the pi manifest in package.json; no build step is required.

The landing page source lives in site/. It uses a sample of 35 public skills from skills.sh, not workspace data; see docs/SAMPLE-DATA.md. It is a static site with no build step:

npx wrangler pages deploy site --project-name pi-skill-families --branch main

Release steps, including npm staged publishing and approval, are in RELEASING.md. Commits use Conventional Commits through cog; the repository config is cog.toml.

License

MIT