@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.
Package details
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
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_startsystem prompt options,registerTool, andwithFileMutationQueue. - 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.
patternsuse*for any characters and?for one.assignmentsare explicit and override patterns.- Unmatched skills fall into
uncategorized. move_skilltouncategorizedpins a skill outside every family.unassign_skillreleases 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/skillsdiscovery 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-invocationskills 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