-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Summary
Add "skill packs" to mpak: a single registry entry that references multiple individual skills. When a user runs mpak skill install @scope/pack-name, mpak fetches the pack manifest, resolves the skill references, and installs each skill individually to ~/.claude/skills/. Claude Code never sees packs directly.
Motivation
Users building workflows often need a set of related skills that work together (e.g., a "DevOps pack" with k8s, docker, and terraform skills). Today they must install each skill individually and know which ones go together. Packs give authors a way to curate and distribute skill bundles.
Design Principles
- Packs are NOT a separate entity. A pack is a skill with
type='pack'. One table, one search, one install command. Users don't think about the distinction. - Version resolution at announce time. Pack versions store immutable snapshots of resolved skill versions.
- Name collision prevention. Cannot publish a pack with the same name as a skill, or vice versa.
- Tracking in
~/.mpak/packs/. mpak's data stays in mpak's directory, not Claude Code's.
User Stories
- Install a pack:
mpak skill install @nimblebrain/devopsfetches the pack manifest, resolves each skill reference, installs all skills to~/.claude/skills/, writes a tracking file to~/.mpak/packs/devops.json. - Search returns both:
mpak skill search devopsshows individual skills and packs (with a type indicator and skill count). Optional--type packfilter. - List shows membership:
mpak skill listshows a PACK column indicating which pack (if any) each installed skill belongs to. - Uninstall a pack:
mpak skill uninstall @nimblebrain/devopsremoves all skills in the pack and the tracking file. - Publish a pack: CI calls
POST /v1/skills/announce-packwith a manifest. The registry validates all referenced skills exist and resolves semver ranges.
Pack Manifest (pack.json)
{
"name": "@nimblebrain/devops",
"version": "1.0.0",
"description": "Essential DevOps skills for cloud infrastructure",
"skills": {
"@nimblebrain/k8s": "^1.0.0",
"@nimblebrain/docker": "^2.1.0",
"@nimblebrain/terraform": ">=1.0.0 <3.0.0"
},
"author": { "name": "NimbleBrain" },
"keywords": ["devops", "cloud", "infrastructure"]
}Scope
In scope
- Zod schemas for pack manifest, announce request/response, tracking file
- Database migration:
typecolumn on Skill, nullable artifact fields + pack fields on SkillVersion - Repository: type filter in search, pack field handling in upsert
- API:
POST /v1/skills/announce-packendpoint, type filter on search, pack info on detail - SDK: type exports (existing
getSkill()already returns enough) - CLI: install (pack detection + parallel skill install), uninstall, list (pack column)
Out of scope (deferred)
mpak skill updatefor packs- Pack dependency resolution (packs cannot depend on other packs)
- Lockfile support
- Pack-level configuration or environment variables
Implementation Sketch
Affected packages
| Package | Changes |
|---|---|
packages/schemas |
New skill-pack.ts, extend skill.ts with type/skills fields |
apps/registry |
Migration (1 new col on Skill, 3 nullable + 3 new on SkillVersion), repository updates, new announce-pack route, search/detail type awareness |
packages/sdk |
Re-export new types |
packages/cli |
Extract reusable installSingleSkill(), new install-pack.ts, new uninstall.ts, list pack column, register uninstall command |
Estimate: 4 new files, ~13 modified files.
Database changes
Skill table: add type VARCHAR(20) DEFAULT 'skill'
SkillVersion table:
- Make nullable:
storage_path,digest,size_bytes(packs have no S3 artifact) - Add:
pack_manifest JSON,resolved_skills JSON,skill_count INT DEFAULT 0
Key API behavior
POST /v1/skills/announce-pack: validates manifest, resolves all skill semver ranges against registry, stores resolved snapshot, rejects if any skill missingGET /v1/skills/search?type=pack: optional type filterGET /v1/skills/@scope/name: includestypeandskills[]array for packs- Name collision: announce-pack rejects if name already exists as
type='skill', and vice versa
CLI behavior
mpak skill install @scope/pack: detectstype='pack'from detail response, installs each skill in parallel viaPromise.allSettled, writes tracking filempak skill uninstall @scope/pack: reads tracking file, removes all skills, deletes tracking filempak skill uninstall @scope/skill: removes single skill, updates any referencing tracking files
Verification
pnpm typecheck && pnpm lint && pnpm test && pnpm buildManual smoke tests:
- Search returns both types with type indicator
- Install pack installs all skills + writes tracking file
- List shows pack membership
- Uninstall pack removes all skills + tracking file
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request