Project 14: Skill Marketplace - Shareable Skill Packages
Build a skill distribution system with package format, installation CLI, version management, and a registry.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Expert |
| Time Estimate | 2-3 weeks |
| Language | Bash + JSON |
| Prerequisites | Projects 9-13 completed, package management concepts |
| Key Topics | Package management, semantic versioning, distribution, CLI design |
| Knowledge Area | Skills / Package Management / Distribution |
| Main Book | “Software Engineering at Google” by Winters et al. |
1. Learning Objectives
By completing this project, you will:
- Design a package format: Create a specification for distributable skill packages
- Build a CLI installer: Implement commands for install, list, update, remove
- Implement version management: Use semantic versioning for compatibility
- Create a registry system: Build infrastructure for skill discovery and distribution
- Handle dependencies: Manage skill-to-skill dependencies
- Apply package manager patterns: Learn from npm, homebrew, and similar tools
2. Theoretical Foundation
2.1 Why a Skill Marketplace?
Currently, skills are shared by copying files. This project creates proper packaging:
┌─────────────────────────────────────────────────────────────────────────┐
│ CURRENT vs MARKETPLACE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ CURRENT (Manual) MARKETPLACE (Automated) │
│ ──────────────── ─────────────────────── │
│ │
│ 1. Find skill on GitHub 1. Search registry │
│ 2. Clone or download ZIP $ claude-skill search review │
│ 3. Copy files to ~/.claude/skills → code-review 2.1.0 │
│ 4. Manually check for updates → pr-reviewer 1.0.3 │
│ 5. No version tracking │
│ 2. Install with one command │
│ $ claude-skill install code-review│
│ │
│ 3. Automatic updates │
│ $ claude-skill update │
│ → code-review 2.1.0 → 2.2.0 │
│ │
│ 4. Version tracking │
│ $ claude-skill list │
│ → code-review 2.2.0 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
2.2 Package Manager Architecture
Learn from established package managers:
┌─────────────────────────────────────────────────────────────────────────┐
│ PACKAGE MANAGER COMPONENTS │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ REGISTRY │ │
│ │ │ │
│ │ - Package index (names, versions, descriptions) │ │
│ │ - Download URLs │ │
│ │ - Metadata (author, license, dependencies) │ │
│ │ │ │
│ │ Examples: │ │
│ │ - npm registry (registry.npmjs.org) │ │
│ │ - Homebrew formulae (GitHub repo) │ │
│ │ - Our approach: GitHub + JSON index │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ CLI │ │
│ │ │ │
│ │ Commands: │ │
│ │ - install <package> Download and install │ │
│ │ - remove <package> Uninstall │ │
│ │ - list Show installed packages │ │
│ │ - update [package] Update to latest version │ │
│ │ - search <query> Find packages │ │
│ │ - info <package> Show package details │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ LOCAL STORAGE │ │
│ │ │ │
│ │ ~/.claude/skills/ │ │
│ │ ├── code-review/ │ │
│ │ │ ├── manifest.json (version, metadata) │ │
│ │ │ ├── SKILL.md │ │
│ │ │ └── ... │ │
│ │ └── web-testing/ │ │
│ │ ├── manifest.json │ │
│ │ └── SKILL.md │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
2.3 Semantic Versioning
Version numbers communicate compatibility:
┌─────────────────────────────────────────────────────────────────────────┐
│ SEMANTIC VERSIONING │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ MAJOR.MINOR.PATCH │
│ 2 . 1 . 3 │
│ │ │ │ │
│ │ │ └── Patch: Bug fixes │
│ │ │ (backward compatible) │
│ │ │ │
│ │ └── Minor: New features │
│ │ (backward compatible) │
│ │ │
│ └── Major: Breaking changes │
│ (may require changes to use) │
│ │
│ Examples: │
│ │
│ 1.0.0 → 1.0.1 Patch: fixed a bug, safe to update │
│ 1.0.1 → 1.1.0 Minor: added new feature, safe to update │
│ 1.1.0 → 2.0.0 Major: breaking change, review before updating │
│ │
│ Version ranges: │
│ │
│ ^1.2.3 Compatible with 1.x.x (>=1.2.3 <2.0.0) │
│ ~1.2.3 Patch updates only (>=1.2.3 <1.3.0) │
│ 1.2.3 Exact version only │
│ >=1.0 Any version 1.0 or higher │
│ │
└─────────────────────────────────────────────────────────────────────────┘
2.4 Package Format
Define what a skill package contains:
my-skill/
├── manifest.json # Package metadata (required)
├── SKILL.md # Main skill file (required)
├── README.md # Human documentation
├── CHANGELOG.md # Version history
├── LICENSE # License file
├── REFERENCES.md # Optional references
├── templates/ # Optional templates
│ └── *.md
└── scripts/ # Optional scripts
└── *.py
manifest.json:
{
"name": "code-review",
"version": "2.1.0",
"description": "Comprehensive code review with specialized subagents",
"author": "Your Name <you@example.com>",
"license": "MIT",
"repository": "github.com/username/code-review",
"keywords": ["code", "review", "quality", "security"],
"dependencies": {
"base-skill": "^1.0.0"
},
"claude-code": {
"minVersion": "1.0.0"
}
}
2.5 Registry Design Options
Three approaches for the registry:
┌─────────────────────────────────────────────────────────────────────────┐
│ REGISTRY OPTIONS │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. GITHUB-BASED (Recommended for starting) │
│ ────────────────────────────────────────── │
│ │
│ Registry: JSON file in a GitHub repo │
│ Packages: GitHub releases │
│ │
│ github.com/claude-skills/registry/ │
│ └── index.json │
│ { │
│ "packages": { │
│ "code-review": { │
│ "repository": "username/code-review", │
│ "version": "2.1.0", │
│ "description": "..." │
│ } │
│ } │
│ } │
│ │
│ ───────────────────────────────────────────────────────────────────── │
│ │
│ 2. SIMPLE FILE SERVER │
│ ───────────────────── │
│ │
│ Registry: JSON file on any web server │
│ Packages: Tar/zip downloads │
│ │
│ https://skills.example.com/ │
│ ├── index.json │
│ └── packages/ │
│ ├── code-review-2.1.0.tar.gz │
│ └── web-testing-1.3.0.tar.gz │
│ │
│ ───────────────────────────────────────────────────────────────────── │
│ │
│ 3. FULL REGISTRY SERVICE │
│ ──────────────────────── │
│ │
│ API server with: │
│ - Package uploads │
│ - Search functionality │
│ - User accounts │
│ - Download stats │
│ │
│ (Most complex, save for later) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
2.6 Security Considerations
Package managers must address security:
| Risk | Mitigation |
|---|---|
| Malicious code | Code review before publishing, signing |
| Typosquatting | Name similarity checks, verified publishers |
| Supply chain attacks | Lock files, integrity hashes |
| Privilege escalation | Sandbox skill execution |
3. Project Specification
3.1 What You Will Build
A skill distribution system with:
- Package format specification (manifest.json + skill files)
- CLI tool for installation and management
- Version tracking and update detection
- Simple GitHub-based registry
3.2 Functional Requirements
- Package Format:
- manifest.json with name, version, description
- SKILL.md as the main skill file
- Support for templates/, scripts/, references
- CLI Commands:
install <name>- Download and install skillremove <name>- Uninstall skilllist- Show installed skills with versionsupdate [name]- Update skill(s) to latestsearch <query>- Find skills in registryinfo <name>- Show skill details
- Version Management:
- Track installed versions in manifest.json
- Detect available updates from registry
- Support semver ranges for dependencies
- Registry:
- JSON index of available skills
- GitHub releases for package downloads
- Publish workflow for contributors
3.3 Non-Functional Requirements
- Reliability: Handle network failures gracefully
- Speed: Cache registry index locally
- Security: Warn about untrusted sources
- Simplicity: Easy to use and contribute
4. Real World Outcome
When you complete this project, here’s exactly what you’ll experience:
# Search for skills
$ claude-skill search review
Searching registry...
RESULTS:
code-review 2.1.0 Comprehensive code review with subagents
pr-reviewer 1.0.3 GitHub PR review assistant
security-scan 0.9.0 Security-focused code analysis
# Install a skill
$ claude-skill install code-review
Installing code-review@2.1.0...
Downloading from github.com/claude-skills/code-review
Extracting to ~/.claude/skills/code-review/
Dependencies: none
Installed successfully!
# List installed skills
$ claude-skill list
INSTALLED SKILLS:
NAME VERSION DESCRIPTION
code-review 2.1.0 Comprehensive code review with subagents
web-testing 1.3.0 Browser automation for web testing
doc-generator 1.0.0 Auto-generate documentation
# Check for updates
$ claude-skill update
Checking for updates...
UPDATES AVAILABLE:
code-review 2.1.0 → 2.2.0
Update code-review? [y/N] y
Downloading code-review@2.2.0...
Installed successfully!
# Get skill info
$ claude-skill info code-review
NAME: code-review
VERSION: 2.2.0
AUTHOR: Claude Skills Team
LICENSE: MIT
REPOSITORY: github.com/claude-skills/code-review
DESCRIPTION:
Comprehensive code review using specialized subagents for
security, performance, style, and testing analysis.
DEPENDENCIES: none
INSTALLED: ~/.claude/skills/code-review/
5. The Core Question You’re Answering
“How can I create an ecosystem for sharing and distributing Claude Code skills, similar to npm or homebrew?”
This project teaches you:
- How package managers work internally
- Specification design for package formats
- CLI design patterns
- Distribution and registry systems
6. Concepts You Must Understand First
6.1 Package Format Design
| Concept | Questions to Answer | Reference |
|---|---|---|
| Metadata requirements | What info must a package have? | npm package.json spec |
| File structure | What files are required/optional? | This guide, section 2.4 |
| Validation | How to verify a valid package? | Schema validation |
6.2 CLI Design
| Concept | Questions to Answer | Reference |
|---|---|---|
| Command structure | How to organize commands? | POSIX conventions |
| Error handling | How to report errors? | Exit codes, messages |
| User experience | How to make it intuitive? | npm, brew as examples |
6.3 Version Management
| Concept | Questions to Answer | Reference |
|---|---|---|
| Semantic versioning | What do version numbers mean? | semver.org |
| Version comparison | How to compare versions? | Semver comparison rules |
| Update detection | How to find newer versions? | Registry queries |
7. Questions to Guide Your Design
7.1 Package Format
What should manifest.json contain?
| Field | Required? | Purpose |
|---|---|---|
| name | Yes | Unique package identifier |
| version | Yes | Semver version string |
| description | Yes | Short description |
| author | No | Package author |
| license | No | License (MIT, Apache, etc.) |
| repository | No | Source code location |
| dependencies | No | Other skills required |
| keywords | No | Search keywords |
7.2 Installation Process
Design the install flow:
┌─────────────────────────────────────────────────────────────────────────┐
│ INSTALL FLOW │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ $ claude-skill install code-review │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 1. Fetch Index │ Download registry index.json │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 2. Find Package │ Look up "code-review" in index │
│ │ │ Get version, repository URL │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 3. Check Local │ Already installed? │
│ │ │ Same version? → Skip │
│ │ │ Older version? → Update │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 4. Download │ Fetch release tarball from GitHub │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 5. Validate │ Check manifest.json exists │
│ │ │ Verify SKILL.md exists │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 6. Extract │ Copy to ~/.claude/skills/<name>/ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 7. Confirm │ "Installed code-review@2.1.0" │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
7.3 Registry Design
For a GitHub-based registry:
| Component | Implementation |
|---|---|
| Index | index.json in registry repo |
| Packages | GitHub releases with tarballs |
| Updates | Compare local version to index |
| Publishing | PR to add entry to index |
8. Thinking Exercise
8.1 Design the Package Format
Sketch the package structure:
my-skill/
├── manifest.json # What fields?
├── SKILL.md # Required
├── ??? # What else is optional?
└── ???
manifest.json design:
{
"name": "???",
"version": "???",
"description": "???",
// What other fields?
}
Questions:
- Should dependencies be other skills or external tools?
- How do you handle breaking changes?
- What validation should the installer perform?
8.2 Trace Through Commands
Walk through each CLI command:
| Command | Steps |
|---|---|
install foo |
Fetch index → Find foo → Download → Extract → Confirm |
list |
Scan skills dir → Read manifests → Format output |
update |
Fetch index → Compare versions → Download new → Replace |
remove foo |
Find foo dir → Delete dir → Confirm |
9. The Interview Questions They’ll Ask
- “How would you design a package manager for AI skills?”
- Expected: Package format, CLI, registry, version management
- Bonus: Security considerations, dependency resolution
- “What are the security considerations for installing third-party skills?”
- Expected: Code review, sandboxing, verified publishers
- Bonus: Signing, integrity verification, permission scopes
- “How do you handle dependency conflicts in package management?”
- Expected: Version ranges, lock files, resolution algorithms
- Bonus: Peer dependencies, hoisting strategies
- “What’s semantic versioning and why does it matter?”
- Expected: MAJOR.MINOR.PATCH meanings
- Bonus: Pre-release versions, build metadata
- “How would you design a registry for community-contributed packages?”
- Expected: Index structure, submission process, discovery
- Bonus: Moderation, quality gates, popularity metrics
10. Solution Architecture
10.1 System Component Diagram
┌─────────────────────────────────────────────────────────────────────────┐
│ SKILL MARKETPLACE ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CLI (claude-skill) │ │
│ │ ───────────────────────────────────────────────────────────── │ │
│ │ │ │
│ │ Commands: │ │
│ │ ├── install - Download and install packages │ │
│ │ ├── remove - Uninstall packages │ │
│ │ ├── list - Show installed packages │ │
│ │ ├── update - Update packages │ │
│ │ ├── search - Find packages │ │
│ │ └── info - Show package details │ │
│ │ │ │
│ └───────────────────────────────┬──────────────────────────────────┘ │
│ │ │
│ ┌───────────────────┼───────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ REGISTRY │ │ LOCAL CACHE │ │ SKILLS DIR │ │
│ │ │ │ │ │ │ │
│ │ github.com/ │ │ ~/.cache/ │ │ ~/.claude/ │ │
│ │ claude-skills/ │ │ claude-skills/ │ │ skills/ │ │
│ │ registry/ │ │ │ │ │ │
│ │ index.json │ │ index.json │ │ code-review/ │ │
│ │ │ │ (cached) │ │ web-testing/ │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ PACKAGE SOURCES │ │
│ │ │ │
│ │ GitHub Releases │ │
│ │ ├── github.com/user/code-review/releases/v2.1.0 │ │
│ │ └── github.com/user/web-testing/releases/v1.3.0 │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
10.2 Data Flow
┌─────────────────────────────────────────────────────────────────────────┐
│ INSTALL COMMAND DATA FLOW │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ $ claude-skill install code-review │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Parse args │ package_name = "code-review" │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Check cache │ ──▶ │ If stale, fetch │ │
│ │ for index.json │ │ from registry │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ └───────────┬───────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ index.json │ │
│ │ { │ │
│ │ "packages": { │ │
│ │ "code-review": { │ │
│ │ "version": "2.1.0", │ │
│ │ "repository": "claude-skills/code-review", │ │
│ │ "description": "..." │ │
│ │ } │ │
│ │ } │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Build URL │ https://github.com/claude-skills/code-review/ │
│ │ │ archive/refs/tags/v2.1.0.tar.gz │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Download tarball│ curl -sL "$url" > /tmp/package.tar.gz │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Extract │ tar -xzf /tmp/package.tar.gz │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Move to skills │ mv extracted/ ~/.claude/skills/code-review/ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Confirm │ "Installed code-review@2.1.0" │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
11. Implementation Guide
11.1 Phase 1: Define Package Format
Create the specification for skill packages:
manifest.json schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["name", "version", "description"],
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z0-9-]+$",
"description": "Package name (lowercase, hyphens allowed)"
},
"version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+",
"description": "Semantic version"
},
"description": {
"type": "string",
"description": "Short description of the skill"
},
"author": {
"type": "string",
"description": "Author name and email"
},
"license": {
"type": "string",
"description": "SPDX license identifier"
},
"repository": {
"type": "string",
"description": "GitHub repository (owner/repo)"
},
"keywords": {
"type": "array",
"items": { "type": "string" },
"description": "Search keywords"
},
"dependencies": {
"type": "object",
"description": "Skill dependencies with version ranges"
},
"claude-code": {
"type": "object",
"properties": {
"minVersion": { "type": "string" }
}
}
}
}
11.2 Phase 2: Build the CLI
Create the main CLI script:
#!/usr/bin/env bash
#
# claude-skill - Skill package manager for Claude Code
#
# Usage:
# claude-skill install <name> Install a skill
# claude-skill remove <name> Uninstall a skill
# claude-skill list List installed skills
# claude-skill update [name] Update skill(s)
# claude-skill search <query> Search registry
# claude-skill info <name> Show skill details
#
set -euo pipefail
# Configuration
SKILLS_DIR="${HOME}/.claude/skills"
CACHE_DIR="${HOME}/.cache/claude-skills"
REGISTRY_URL="https://raw.githubusercontent.com/claude-skills/registry/main/index.json"
CACHE_TTL=3600 # 1 hour
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Ensure directories exist
mkdir -p "$SKILLS_DIR" "$CACHE_DIR"
#
# Utility functions
#
log_info() {
echo -e "${BLUE}INFO:${NC} $1"
}
log_success() {
echo -e "${GREEN}SUCCESS:${NC} $1"
}
log_warning() {
echo -e "${YELLOW}WARNING:${NC} $1"
}
log_error() {
echo -e "${RED}ERROR:${NC} $1" >&2
}
# Fetch registry index (with caching)
fetch_index() {
local cache_file="$CACHE_DIR/index.json"
local now=$(date +%s)
# Check if cache exists and is fresh
if [[ -f "$cache_file" ]]; then
local cache_time=$(stat -f %m "$cache_file" 2>/dev/null || stat -c %Y "$cache_file")
local age=$((now - cache_time))
if [[ $age -lt $CACHE_TTL ]]; then
cat "$cache_file"
return 0
fi
fi
# Fetch fresh index
log_info "Fetching registry index..."
if curl -sf "$REGISTRY_URL" -o "$cache_file"; then
cat "$cache_file"
else
log_error "Failed to fetch registry index"
# Fall back to cache if available
if [[ -f "$cache_file" ]]; then
log_warning "Using cached index"
cat "$cache_file"
else
exit 1
fi
fi
}
# Get package info from index
get_package() {
local name=$1
local index=$(fetch_index)
echo "$index" | jq -r ".packages[\"$name\"] // empty"
}
#
# Commands
#
cmd_install() {
local name=$1
local force=${2:-false}
log_info "Installing $name..."
# Get package info
local pkg=$(get_package "$name")
if [[ -z "$pkg" ]]; then
log_error "Package '$name' not found in registry"
exit 1
fi
local version=$(echo "$pkg" | jq -r '.version')
local repo=$(echo "$pkg" | jq -r '.repository')
# Check if already installed
local target_dir="$SKILLS_DIR/$name"
if [[ -d "$target_dir" ]] && [[ "$force" != "true" ]]; then
local installed_version=$(jq -r '.version' "$target_dir/manifest.json" 2>/dev/null || echo "unknown")
if [[ "$installed_version" == "$version" ]]; then
log_info "$name@$version is already installed"
return 0
else
log_info "Upgrading $name from $installed_version to $version"
fi
fi
# Download from GitHub
local url="https://github.com/${repo}/archive/refs/tags/v${version}.tar.gz"
local tmp_file=$(mktemp)
local tmp_dir=$(mktemp -d)
log_info "Downloading from $repo..."
if ! curl -sL "$url" -o "$tmp_file"; then
log_error "Failed to download $name@$version"
rm -f "$tmp_file"
rm -rf "$tmp_dir"
exit 1
fi
# Extract
tar -xzf "$tmp_file" -C "$tmp_dir"
rm -f "$tmp_file"
# Find extracted directory (GitHub adds version suffix)
local extracted=$(find "$tmp_dir" -mindepth 1 -maxdepth 1 -type d | head -1)
# Validate package
if [[ ! -f "$extracted/manifest.json" ]]; then
log_error "Invalid package: missing manifest.json"
rm -rf "$tmp_dir"
exit 1
fi
if [[ ! -f "$extracted/SKILL.md" ]]; then
log_error "Invalid package: missing SKILL.md"
rm -rf "$tmp_dir"
exit 1
fi
# Install
rm -rf "$target_dir"
mv "$extracted" "$target_dir"
rm -rf "$tmp_dir"
log_success "Installed $name@$version"
}
cmd_remove() {
local name=$1
local target_dir="$SKILLS_DIR/$name"
if [[ ! -d "$target_dir" ]]; then
log_error "Package '$name' is not installed"
exit 1
fi
rm -rf "$target_dir"
log_success "Removed $name"
}
cmd_list() {
echo "INSTALLED SKILLS:"
echo ""
printf " %-15s %-10s %s\n" "NAME" "VERSION" "DESCRIPTION"
printf " %-15s %-10s %s\n" "----" "-------" "-----------"
for dir in "$SKILLS_DIR"/*/; do
if [[ -f "$dir/manifest.json" ]]; then
local name=$(basename "$dir")
local version=$(jq -r '.version // "unknown"' "$dir/manifest.json")
local desc=$(jq -r '.description // ""' "$dir/manifest.json" | cut -c1-40)
printf " %-15s %-10s %s\n" "$name" "$version" "$desc"
fi
done
}
cmd_update() {
local name=${1:-}
log_info "Checking for updates..."
local updates=()
if [[ -n "$name" ]]; then
# Update specific package
local target_dir="$SKILLS_DIR/$name"
if [[ ! -d "$target_dir" ]]; then
log_error "Package '$name' is not installed"
exit 1
fi
updates=("$name")
else
# Check all packages
for dir in "$SKILLS_DIR"/*/; do
if [[ -f "$dir/manifest.json" ]]; then
updates+=("$(basename "$dir")")
fi
done
fi
local has_updates=false
for pkg in "${updates[@]}"; do
local target_dir="$SKILLS_DIR/$pkg"
local installed=$(jq -r '.version' "$target_dir/manifest.json" 2>/dev/null || echo "0.0.0")
local remote=$(get_package "$pkg")
if [[ -z "$remote" ]]; then
continue
fi
local available=$(echo "$remote" | jq -r '.version')
if [[ "$installed" != "$available" ]]; then
has_updates=true
echo " $pkg: $installed → $available"
fi
done
if [[ "$has_updates" == "false" ]]; then
log_info "All packages are up to date"
return 0
fi
echo ""
read -p "Update all? [y/N] " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
for pkg in "${updates[@]}"; do
cmd_install "$pkg" "true"
done
fi
}
cmd_search() {
local query=$1
local index=$(fetch_index)
echo "SEARCH RESULTS for '$query':"
echo ""
echo "$index" | jq -r --arg q "$query" '
.packages | to_entries |
map(select(.key | contains($q) or .value.description | contains($q))) |
.[] |
" \(.key)\t\(.value.version)\t\(.value.description)"
' | column -t -s $'\t'
}
cmd_info() {
local name=$1
local target_dir="$SKILLS_DIR/$name"
if [[ -d "$target_dir" ]] && [[ -f "$target_dir/manifest.json" ]]; then
# Show installed package info
local manifest="$target_dir/manifest.json"
echo "NAME: $(jq -r '.name' "$manifest")"
echo "VERSION: $(jq -r '.version' "$manifest")"
echo "AUTHOR: $(jq -r '.author // "Unknown"' "$manifest")"
echo "LICENSE: $(jq -r '.license // "Unknown"' "$manifest")"
echo "REPOSITORY: $(jq -r '.repository // "Unknown"' "$manifest")"
echo ""
echo "DESCRIPTION:"
jq -r '.description' "$manifest" | fold -w 60 -s | sed 's/^/ /'
echo ""
echo "INSTALLED: $target_dir"
else
# Show registry info
local pkg=$(get_package "$name")
if [[ -z "$pkg" ]]; then
log_error "Package '$name' not found"
exit 1
fi
echo "NAME: $name"
echo "VERSION: $(echo "$pkg" | jq -r '.version')"
echo "REPOSITORY: $(echo "$pkg" | jq -r '.repository')"
echo ""
echo "DESCRIPTION:"
echo "$pkg" | jq -r '.description' | fold -w 60 -s | sed 's/^/ /'
echo ""
echo "STATUS: Not installed"
fi
}
#
# Main
#
cmd=$1
shift || true
case "$cmd" in
install)
[[ -z "${1:-}" ]] && { echo "Usage: claude-skill install <name>"; exit 1; }
cmd_install "$1"
;;
remove|uninstall)
[[ -z "${1:-}" ]] && { echo "Usage: claude-skill remove <name>"; exit 1; }
cmd_remove "$1"
;;
list|ls)
cmd_list
;;
update|upgrade)
cmd_update "${1:-}"
;;
search)
[[ -z "${1:-}" ]] && { echo "Usage: claude-skill search <query>"; exit 1; }
cmd_search "$1"
;;
info)
[[ -z "${1:-}" ]] && { echo "Usage: claude-skill info <name>"; exit 1; }
cmd_info "$1"
;;
help|--help|-h)
cat <<EOF
claude-skill - Skill package manager for Claude Code
USAGE:
claude-skill <command> [options]
COMMANDS:
install <name> Install a skill from the registry
remove <name> Uninstall an installed skill
list List all installed skills
update [name] Update skill(s) to latest version
search <query> Search for skills in the registry
info <name> Show information about a skill
help Show this help message
EXAMPLES:
claude-skill install code-review
claude-skill list
claude-skill update
claude-skill search review
EOF
;;
*)
log_error "Unknown command: $cmd"
echo "Run 'claude-skill help' for usage"
exit 1
;;
esac
11.3 Phase 3: Create Registry Index
Create a simple registry structure:
index.json:
{
"version": "1.0.0",
"updated": "2024-01-15T00:00:00Z",
"packages": {
"code-review": {
"version": "2.1.0",
"description": "Comprehensive code review with specialized subagents",
"repository": "claude-skills/code-review",
"author": "Claude Skills Team",
"license": "MIT",
"keywords": ["review", "code", "quality", "security"]
},
"web-testing": {
"version": "1.3.0",
"description": "Browser automation for web testing",
"repository": "claude-skills/web-testing",
"author": "Claude Skills Team",
"license": "MIT",
"keywords": ["test", "browser", "automation", "e2e"]
},
"doc-generator": {
"version": "1.0.0",
"description": "Auto-generate documentation from code",
"repository": "claude-skills/doc-generator",
"author": "Claude Skills Team",
"license": "MIT",
"keywords": ["documentation", "docstring", "jsdoc"]
}
}
}
11.4 Phase 4: Install the CLI
# Make executable
chmod +x claude-skill
# Add to PATH (choose one):
# Option 1: Move to /usr/local/bin
sudo mv claude-skill /usr/local/bin/
# Option 2: Add to ~/bin and update PATH
mkdir -p ~/bin
mv claude-skill ~/bin/
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# Verify
claude-skill help
12. Hints in Layers
Hint 1: Start with Local Packages
First, build an installer that works with local directories. No network yet.
# Create a local package
mkdir -p /tmp/test-skill
echo '{"name":"test-skill","version":"1.0.0","description":"Test"}' > /tmp/test-skill/manifest.json
echo "# Test Skill" > /tmp/test-skill/SKILL.md
# Install from local path
claude-skill install-local /tmp/test-skill
Hint 2: Add GitHub Support
Use GitHub release URLs to fetch packages:
url="https://github.com/${repo}/archive/refs/tags/v${version}.tar.gz"
curl -sL "$url" | tar -xz -C "$SKILLS_DIR"
Hint 3: Create a Simple Registry
A JSON file listing packages with their GitHub URLs is enough:
{
"packages": {
"my-skill": {
"version": "1.0.0",
"repository": "owner/repo"
}
}
}
Host on GitHub Pages or raw.githubusercontent.com.
Hint 4: Add Version Checking
Compare installed version with registry:
installed=$(jq -r '.version' "$SKILLS_DIR/$name/manifest.json")
available=$(get_package "$name" | jq -r '.version')
if [[ "$installed" != "$available" ]]; then
echo "Update available: $installed → $available"
fi
13. Common Pitfalls & Debugging
13.1 Frequent Mistakes
| Pitfall | Symptom | Solution |
|---|---|---|
| Missing jq | “command not found” | Install jq: brew install jq |
| curl fails silently | Empty packages | Add error checking with curl -f |
| Wrong extract path | Files in wrong directory | Handle GitHub’s version suffix in tarball |
| Cache not updating | Stale package list | Check cache TTL logic |
| Permissions | Can’t write to skills dir | Check ~/.claude/skills permissions |
13.2 Debugging Steps
- Test commands manually: Run curl, tar, jq separately
- Check cache:
cat ~/.cache/claude-skills/index.json - Verify package:
ls -la ~/.claude/skills/package-name/ - Check manifest:
cat ~/.claude/skills/package-name/manifest.json
14. Extensions & Challenges
14.1 Beginner Extensions
- Add
--versionflag to show CLI version - Color-code outdated packages in list
- Add
--forceflag to reinstall
14.2 Intermediate Extensions
- Dependency resolution (install deps first)
- Lock file for reproducible installs
- Integrity checking with SHA hashes
- Multiple registry support
14.3 Advanced Extensions
- Publishing workflow (create releases)
- Namespace/scopes (@user/skill)
- Private registries
- Skill signing and verification
15. Books That Will Help
| Topic | Book/Resource | Chapter/Section |
|---|---|---|
| Package management | “Software Engineering at Google” | Chapter 21: Dependency Management |
| CLI design | “Build Awesome CLIs with Node.js” | All chapters |
| Versioning | semver.org | Full specification |
| Shell scripting | “The Linux Command Line” | Chapters on bash scripting |
16. Self-Assessment Checklist
Understanding
- I can explain the package format specification
- I understand semantic versioning
- I know how registries work
- I can describe the install/update flow
Implementation
- CLI installs packages from GitHub
- Version comparison works correctly
- List shows all installed skills
- Update detects newer versions
Growth
- I can add new packages to the registry
- I can extend the CLI with new commands
- I understand security considerations
17. Learning Milestones
| Milestone | Indicator |
|---|---|
| Local installation works | You understand package structure |
| GitHub packages install | You understand distribution |
| Version checking works | You understand semver comparison |
| Registry index works | You’ve built a distribution system |
This guide was expanded from CLAUDE_CODE_MASTERY_40_PROJECTS.md. For the complete learning path, see the project index.