Project 23: Output Style Library - Shareable Style Ecosystem
Project 23: Output Style Library - Shareable Style Ecosystem
Build a complete ecosystem for sharing, discovering, and managing Claude Code output styles: a CLI tool for search, install, and validation, plus a community registry for style distribution.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Advanced (Level 3) |
| Time Estimate | 2 weeks |
| Language | Bash + JSON (Alternatives: Python, TypeScript/Bun) |
| Prerequisites | Projects 21-22 completed, Project 14 (skill marketplace) patterns, basic package management understanding |
| Key Topics | Style validation, registry design, version management, community distribution, CLI tools |
| Claude Code Features | Output Styles, YAML frontmatter, ~/.claude/output-styles/ directory |
1. Learning Objectives
By completing this project, you will:
- Design package ecosystems: Understand how package managers (npm, pip, brew) work and apply those patterns to AI configuration
- Implement schema validation: Build validators that verify output styles are correctly formatted and complete
- Create distribution systems: Design registries for discovering and sharing community contributions
- Build developer-friendly CLIs: Create intuitive command-line interfaces following Unix conventions
- Handle versioning: Implement semantic versioning for configuration files
- Manage open source workflows: Learn contribution patterns, code review, and community management
2. Deep Theoretical Foundation
2.1 The Problem: Isolated Configuration
Output styles are powerful but currently isolated. Each developer creates their own, with no way to:
- Discover what others have created
- Share successful patterns with teammates
- Benefit from community improvements
- Ensure consistency across teams
CURRENT STATE: ISOLATED STYLES
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Developer A โ โ Developer B โ โ Developer C โ
โ โ โ โ โ โ
โ โโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโ โ
โ โtech-writerโ โ โ โtech-docs โ โ โ โdoc-helper โ โ
โ โ(v1.0) โ โ โ โ(v2.1) โ โ โ โ(v1.5) โ โ
โ โโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโ โ
โ โ โ โ โ โ
โ All solving โ โ Same problem โ โ Duplicate โ
โ same problem โ โ independently โ โ effort โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ
โผ
DESIRED STATE: SHARED ECOSYSTEM
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STYLE REGISTRY โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ tech-writer@2.1.0 โ โ
โ โ "Technical documentation with formal tone" โ โ
โ โ Downloads: 1,234 | โญ 4.8 | Author: @expert_writer โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ code-review@1.5.0 โ โ
โ โ "Systematic code review assistant" โ โ
โ โ Downloads: 892 | โญ 4.6 | Author: @review_pro โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ โ
โผ โผ โผ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Developer A โ โ Developer B โ โ Developer C โ
โ โ โ โ โ โ
โ $ claude-stylesโ โ $ claude-stylesโ โ $ claude-stylesโ
โ install โ โ install โ โ install โ
โ tech-writer โ โ tech-writer โ โ tech-writer โ
โ โ โ โ โ โ
โ Same style, โ โ Consistent โ โ Community โ
โ automatic โ โ across team โ โ updates โ
โ updates โ โ โ โ โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
2.2 Package Manager Architecture Patterns
From โSoftware Engineering at Googleโ (Winters et al.), package ecosystems share common patterns:
PACKAGE MANAGER ARCHITECTURE
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CLI TOOL โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ COMMANDS โ โ
โ โ โ โ
โ โ search <query> - Find packages by name/keyword โ โ
โ โ install <name> - Download and install package โ โ
โ โ uninstall <name> - Remove installed package โ โ
โ โ list - Show installed packages โ โ
โ โ update [name] - Update to latest version โ โ
โ โ validate <file> - Check package is well-formed โ โ
โ โ publish <file> - Submit to registry โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ REGISTRY โ
โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ index.json โ โ Package Storage โ โ
โ โ โ โ โ โ
โ โ - Package list โ โ - Raw files โ โ
โ โ - Metadata โ โ - Version dirs โ โ
โ โ - Downloads โ โ - Checksums โ โ
โ โ - Ratings โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Protocol: HTTPS โ
โ Format: JSON for metadata, raw files for content โ
โ Versioning: Semantic versioning (major.minor.patch) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LOCAL STORAGE โ
โ โ
โ ~/.claude/output-styles/ โ
โ โโโ tech-writer.md โ
โ โโโ code-review.md โ
โ โโโ .registry/ โ
โ โโโ installed.json (tracking file) โ
โ โโโ cache/ (downloaded metadata) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2.3 Style Validation Requirements
Before sharing styles, they must be validated. A valid output style:
---
name: style-name # REQUIRED: Identifier (a-z, 0-9, hyphens)
description: Description # OPTIONAL but recommended
keep-coding-instructions: true/false # OPTIONAL, defaults to true
version: 1.0.0 # REQUIRED for registry (semver)
author: @username # REQUIRED for registry
license: MIT # OPTIONAL, defaults to MIT
tags: # OPTIONAL for discovery
- documentation
- technical
---
# Style Content
[At least 10 lines of meaningful content]
Validation Rules:
VALIDATION CHECKLIST
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ FRONTMATTER VALIDATION โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ [ ] name: Required โ
โ - Format: lowercase, alphanumeric, hyphens only โ
โ - Length: 2-50 characters โ
โ - Must be unique in registry โ
โ โ
โ [ ] version: Required for registry โ
โ - Format: semver (X.Y.Z) โ
โ - Must be higher than existing versions โ
โ โ
โ [ ] description: Recommended โ
โ - Length: 10-200 characters โ
โ - No markdown in description โ
โ โ
โ [ ] keep-coding-instructions: Optional โ
โ - Must be boolean if present โ
โ โ
โ [ ] author: Required for registry โ
โ - Format: @username or email โ
โ โ
โ [ ] tags: Optional โ
โ - Array of lowercase strings โ
โ - Max 5 tags โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CONTENT VALIDATION โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ [ ] Markdown body exists and is non-empty โ
โ โ
โ [ ] Minimum 10 lines of content (excluding empty lines) โ
โ โ
โ [ ] At least one heading (# or ##) โ
โ โ
โ [ ] No obvious placeholder text ("TODO", "XXX") โ
โ โ
โ [ ] No sensitive data (API keys, passwords) โ
โ โ
โ [ ] Valid markdown syntax โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2.4 Registry Design
A simple registry uses GitHub as a backend:
GITHUB-BASED REGISTRY
github.com/claude-styles/registry/
โ
โโโ index.json # Main registry index
โ {
โ "styles": [
โ {
โ "name": "tech-writer",
โ "version": "2.1.0",
โ "description": "Technical documentation...",
โ "author": "@expert_writer",
โ "url": "https://raw.githubusercontent.com/...",
โ "downloads": 1234,
โ "rating": 4.8,
โ "tags": ["documentation", "technical"]
โ },
โ ...
โ ],
โ "updated": "2025-01-15T10:30:00Z"
โ }
โ
โโโ styles/ # Raw style files
โ โโโ tech-writer/
โ โ โโโ 2.1.0.md # Versioned files
โ โ โโโ 2.0.0.md
โ โ โโโ 1.0.0.md
โ โ
โ โโโ code-review/
โ โ โโโ 1.5.0.md
โ โ
โ โโโ ...
โ
โโโ README.md # Contribution guide
Index Schema:
interface StyleIndex {
styles: StyleMetadata[];
updated: string; // ISO 8601 timestamp
}
interface StyleMetadata {
name: string;
version: string;
description: string;
author: string;
url: string;
downloads: number;
rating: number;
tags: string[];
created: string;
updated: string;
dependencies?: string[]; // Other styles this depends on
}
2.5 Version Management with Semantic Versioning
From the semver specification:
SEMANTIC VERSIONING
MAJOR.MINOR.PATCH
โ โ โ
โ โ โโโ Bug fixes, clarifications
โ โ (2.1.0 โ 2.1.1)
โ โ
โ โโโโโโโ New features, backward compatible
โ (2.0.0 โ 2.1.0)
โ
โโโโโโโโโโโ Breaking changes
(1.x.x โ 2.0.0)
For Output Styles:
โโโโโโโโโโโโโโโโโ
MAJOR bump when:
โข Fundamentally different output format
โข Removed sections or requirements
โข Changed tone significantly
MINOR bump when:
โข Added new optional sections
โข Enhanced existing behavior
โข Added new keywords/patterns
PATCH bump when:
โข Fixed typos
โข Clarified instructions
โข Minor wording improvements
2.6 Installation and Conflict Resolution
INSTALLATION WORKFLOW
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ $ claude-styles install tech-writer@2.1.0 โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. FETCH METADATA โ
โ โ
โ GET https://registry/index.json โ
โ โ Find style "tech-writer" version "2.1.0" โ
โ โ Get download URL โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. CHECK CONFLICTS โ
โ โ
โ Does ~/.claude/output-styles/tech-writer.md exist? โ
โ โ
โ IF YES: โ
โ โโโ Is it the same version? โ Already installed, skip โ
โ โโโ Is it a different version? โ Ask: upgrade or keep? โ
โ โโโ Is it a local file (no version)? โ Warn and backup โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. DOWNLOAD AND VALIDATE โ
โ โ
โ GET https://registry/styles/tech-writer/2.1.0.md โ
โ โ Validate frontmatter โ
โ โ Check content requirements โ
โ โ Verify checksum (if provided) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. INSTALL โ
โ โ
โ WRITE ~/.claude/output-styles/tech-writer.md โ
โ UPDATE ~/.claude/output-styles/.registry/installed.json โ
โ โ
โ installed.json: โ
โ { โ
โ "tech-writer": { โ
โ "version": "2.1.0", โ
โ "installed": "2025-01-15T10:30:00Z", โ
โ "source": "registry" โ
โ } โ
โ } โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 5. CONFIRM โ
โ โ
โ โ
Installed tech-writer@2.1.0 โ
โ Use with: claude --output-style tech-writer โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
3. The Core Question Youโre Answering
โHow can I create an ecosystem for sharing and discovering output styles, enabling community contributions?โ
Output styles are powerful but currently isolated. This project creates infrastructure for the Claude Code community to share, discover, and collaborate on behavior customizations.
4. Concepts You Must Understand First
Stop and research these before coding:
4.1 Style Validation
- What makes a valid output style?
- Required frontmatter fields?
- Markdown body requirements?
- Reference: Claude Code Docs - Output Styles
4.2 Registry Design
- How to organize styles (categories, tags)?
- Metadata for discovery (ratings, downloads)?
- Version management?
- Reference: npm registry patterns, Homebrew tap structure
4.3 Installation Workflow
- Where do styles get installed (
~/.claude/output-styles/)? - How to handle conflicts?
- User vs project scope?
4.4 CLI Design
- Unix command conventions
- User-friendly output formatting
- Error handling and messaging
- Reference: โThe Art of Unix Programmingโ by Eric Raymond
5. Questions to Guide Your Design
Before implementing, think through these:
5.1 Registry Storage
Where should the registry live?
- GitHub: Simple, free, PRs for contributions
- Custom Server: More control, requires hosting
- Distributed: Multiple registries, federation
5.2 Metadata Structure
What information is needed for each style?
- Name, version, description
- Author, license
- Download count, ratings
- Tags for categorization
- Dependencies (optional)
5.3 Update Strategy
How do users get updates?
- Manual:
claude-styles update tech-writer - Check on use: Warn if newer version available
- Automatic: Background updates (risky)
6. Thinking Exercise
Design Your Registry Schema
Before writing code, sketch out the data structures:
// index.json structure
{
"styles": [
{
"name": "tech-writer",
"version": "2.1.0",
"description": "...",
// What other fields?
}
]
}
# tech-writer.md - The actual output style
---
name: tech-writer
description: Technical writing assistant
keep-coding-instructions: true
version: 2.1.0
author: @expert_writer
tags:
- documentation
- technical
---
[Style content here]
Design Questions:
- Should metadata be in the style file or separate?
- In file: Self-contained, version always matches
- Separate: Easier to query, but can become inconsistent
- How do you handle style updates?
- Immutable versions (new file for each version)
- Mutable (overwrite existing)
- What about style dependencies?
- Style A requires Style B to be installed
- Shared base styles extended by specific ones
7. Real World Outcome
7.1 Example CLI Session
$ claude-styles search "documentation"
Found 5 output styles:
๐ tech-writer (v2.1.0)
Technical documentation with formal tone
โญ 4.8 | Downloads: 1,234 | Tags: documentation, technical
๐ api-docs (v1.5.0)
REST API documentation generator
โญ 4.6 | Downloads: 892 | Tags: api, documentation
๐ changelog (v1.0.3)
Structured changelog entries
โญ 4.5 | Downloads: 567 | Tags: changelog, releases
๐ tutorial-writer (v1.2.0)
Step-by-step tutorial creator
โญ 4.3 | Downloads: 445 | Tags: tutorial, education
๐ readme-generator (v2.0.0)
README.md file generator
โญ 4.1 | Downloads: 321 | Tags: readme, documentation
---
$ claude-styles install tech-writer
๐ฆ Installing tech-writer@2.1.0...
Downloaded from github.com/claude-styles/registry
Validated frontmatter and content
Installed to ~/.claude/output-styles/tech-writer.md
โ
Installed! Use with: claude --output-style tech-writer
---
$ claude-styles list
Installed Output Styles:
โโโ tech-writer 2.1.0 Technical documentation with formal tone
โโโ code-review 1.2.0 Code review assistant
โโโ learning 1.0.0 Educational explanations
3 styles installed
---
$ claude-styles validate ./my-custom-style.md
Validating my-custom-style.md...
โ
Frontmatter:
โโโ name: my-custom-style โ
โโโ version: 1.0.0 โ
โโโ description: "Custom style for my team" โ
โโโ keep-coding-instructions: true โ
โ
Content:
โโโ Line count: 45 (minimum 10) โ
โโโ Has headings: yes โ
โโโ No placeholder text: yes โ
โ
Valid output style! Ready for use or publication.
---
$ claude-styles update tech-writer
Checking for updates...
tech-writer: 2.1.0 โ 2.2.0 available
Changes in 2.2.0:
โข Added RFC-style proposal templates
โข Improved ASCII diagram guidelines
โข Fixed typo in example output
Update? [Y/n] y
๐ฆ Updating tech-writer to 2.2.0...
Downloaded new version
Backed up previous version to tech-writer.2.1.0.bak
โ
Updated to tech-writer@2.2.0
---
$ claude-styles publish ./my-custom-style.md
Publishing my-custom-style@1.0.0...
โ
Validated style
โ
Checked name availability
โ
Created pull request: github.com/claude-styles/registry/pull/42
Your style will be reviewed and published once approved.
Track status: https://github.com/claude-styles/registry/pull/42
8. The Interview Questions Theyโll Ask
- โHow would you design a registry for AI behavior templates?โ
- Discuss storage options (GitHub, custom server, distributed)
- Explain metadata requirements for discovery
- Address trust and security concerns
- โWhat metadata is needed for style discovery?โ
- Name, description, tags for search
- Downloads, ratings for popularity
- Version, author for provenance
- Dependencies for complex styles
- โHow do you handle versioning for behavior configurations?โ
- Semantic versioning principles
- What constitutes breaking changes for styles
- Upgrade paths and migration
- โWhat are the security considerations for user-contributed styles?โ
- Styles can contain instructions that change AI behavior
- Review process before publishing
- Sandboxing or limiting what styles can do
- Provenance and author verification
- โHow would you implement style validation?โ
- Schema validation for frontmatter
- Content requirements (minimum length, headings)
- Security checks (no sensitive data)
- Linting for common issues
9. Hints in Layers
Hint 1: Reuse Skill Marketplace Patterns
The architecture from Project 14 (skill marketplace) applies here with modifications:
- Registry index structure
- CLI command patterns
- Installation workflow
Hint 2: Validate Frontmatter with YAML Parser
Use a proper YAML parser, donโt regex:
# In Python
import yaml
with open(style_file) as f:
content = f.read()
# Split frontmatter from content
if content.startswith('---'):
_, frontmatter, body = content.split('---', 2)
meta = yaml.safe_load(frontmatter)
Hint 3: Simple GitHub Registry
Start simple - a JSON file listing styles with GitHub raw URLs is enough:
REGISTRY_URL="https://raw.githubusercontent.com/claude-styles/registry/main/index.json"
curl -s "$REGISTRY_URL" | jq '.styles[] | select(.name == "tech-writer")'
Hint 4: Add Categories
Allow filtering by tags: documentation, review, learning, creative, code, etc.
10. Complete Implementation
10.1 CLI Tool Structure
Create the CLI at ~/.local/bin/claude-styles:
#!/usr/bin/env bash
#
# claude-styles - Output style package manager for Claude Code
#
# Usage:
# claude-styles search <query>
# claude-styles install <name>[@version]
# claude-styles uninstall <name>
# claude-styles list
# claude-styles update [name]
# claude-styles validate <file>
# claude-styles publish <file>
#
set -euo pipefail
# Configuration
STYLES_DIR="${HOME}/.claude/output-styles"
REGISTRY_DIR="${STYLES_DIR}/.registry"
INSTALLED_FILE="${REGISTRY_DIR}/installed.json"
REGISTRY_URL="${CLAUDE_STYLES_REGISTRY:-https://raw.githubusercontent.com/claude-styles/registry/main/index.json}"
# Ensure directories exist
mkdir -p "${STYLES_DIR}" "${REGISTRY_DIR}"
# Initialize installed.json if it doesn't exist
if [[ ! -f "${INSTALLED_FILE}" ]]; then
echo '{}' > "${INSTALLED_FILE}"
fi
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging functions
log_info() { echo -e "${BLUE}$1${NC}"; }
log_success() { echo -e "${GREEN}$1${NC}"; }
log_warn() { echo -e "${YELLOW}$1${NC}"; }
log_error() { echo -e "${RED}$1${NC}" >&2; }
# Fetch registry index
fetch_registry() {
curl -sf "${REGISTRY_URL}" 2>/dev/null || {
log_error "Failed to fetch registry from ${REGISTRY_URL}"
exit 1
}
}
# Command: search
cmd_search() {
local query="${1:-}"
if [[ -z "$query" ]]; then
log_error "Usage: claude-styles search <query>"
exit 1
fi
log_info "Searching for '${query}'..."
echo
local registry
registry=$(fetch_registry)
local results
results=$(echo "$registry" | jq -r --arg q "$query" '
.styles[] |
select(
(.name | test($q; "i")) or
(.description | test($q; "i")) or
(.tags[]? | test($q; "i"))
) |
"๐ \(.name) (v\(.version))\n \(.description)\n โญ \(.rating // "N/A") | Downloads: \(.downloads // 0) | Tags: \(.tags // [] | join(", "))\n"
')
if [[ -z "$results" ]]; then
echo "No styles found matching '${query}'"
else
local count
count=$(echo "$registry" | jq --arg q "$query" '
[.styles[] | select(
(.name | test($q; "i")) or
(.description | test($q; "i")) or
(.tags[]? | test($q; "i"))
)] | length
')
echo "Found ${count} output styles:"
echo
echo -e "$results"
fi
}
# Command: install
cmd_install() {
local spec="${1:-}"
if [[ -z "$spec" ]]; then
log_error "Usage: claude-styles install <name>[@version]"
exit 1
fi
# Parse name@version
local name version
if [[ "$spec" == *@* ]]; then
name="${spec%@*}"
version="${spec#*@}"
else
name="$spec"
version=""
fi
log_info "Installing ${name}${version:+@$version}..."
local registry
registry=$(fetch_registry)
# Find the style
local style_meta
if [[ -n "$version" ]]; then
style_meta=$(echo "$registry" | jq -r --arg n "$name" --arg v "$version" '
.styles[] | select(.name == $n and .version == $v)
')
else
# Get latest version
style_meta=$(echo "$registry" | jq -r --arg n "$name" '
[.styles[] | select(.name == $n)] | sort_by(.version) | last
')
fi
if [[ -z "$style_meta" || "$style_meta" == "null" ]]; then
log_error "Style '${name}${version:+@$version}' not found in registry"
exit 1
fi
local found_version url
found_version=$(echo "$style_meta" | jq -r '.version')
url=$(echo "$style_meta" | jq -r '.url')
local target_file="${STYLES_DIR}/${name}.md"
# Check for existing installation
if [[ -f "$target_file" ]]; then
local installed_version
installed_version=$(jq -r --arg n "$name" '.[$n].version // "unknown"' "$INSTALLED_FILE")
if [[ "$installed_version" == "$found_version" ]]; then
log_warn "${name}@${found_version} is already installed"
exit 0
else
log_warn "Existing installation found: ${name}@${installed_version}"
read -rp "Replace with ${found_version}? [Y/n] " confirm
if [[ "${confirm:-Y}" != [Yy]* ]]; then
echo "Installation cancelled"
exit 0
fi
# Backup existing
cp "$target_file" "${target_file}.${installed_version}.bak"
fi
fi
# Download the style
log_info " Downloading from ${url}..."
local content
content=$(curl -sf "$url") || {
log_error "Failed to download style"
exit 1
}
# Validate
if ! validate_content "$content" >/dev/null 2>&1; then
log_error "Downloaded style failed validation"
exit 1
fi
# Install
echo "$content" > "$target_file"
# Update installed.json
local now
now=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
jq --arg n "$name" --arg v "$found_version" --arg t "$now" \
'.[$n] = {"version": $v, "installed": $t, "source": "registry"}' \
"$INSTALLED_FILE" > "${INSTALLED_FILE}.tmp"
mv "${INSTALLED_FILE}.tmp" "$INSTALLED_FILE"
echo
log_success "โ
Installed ${name}@${found_version}"
echo " Use with: claude --output-style ${name}"
}
# Command: uninstall
cmd_uninstall() {
local name="${1:-}"
if [[ -z "$name" ]]; then
log_error "Usage: claude-styles uninstall <name>"
exit 1
fi
local target_file="${STYLES_DIR}/${name}.md"
if [[ ! -f "$target_file" ]]; then
log_error "Style '${name}' is not installed"
exit 1
fi
read -rp "Remove ${name}? [Y/n] " confirm
if [[ "${confirm:-Y}" != [Yy]* ]]; then
echo "Uninstallation cancelled"
exit 0
fi
rm "$target_file"
# Update installed.json
jq --arg n "$name" 'del(.[$n])' "$INSTALLED_FILE" > "${INSTALLED_FILE}.tmp"
mv "${INSTALLED_FILE}.tmp" "$INSTALLED_FILE"
log_success "โ
Uninstalled ${name}"
}
# Command: list
cmd_list() {
log_info "Installed Output Styles:"
echo
local count=0
for file in "${STYLES_DIR}"/*.md; do
[[ -f "$file" ]] || continue
local name
name=$(basename "$file" .md)
# Skip hidden files
[[ "$name" == .* ]] && continue
local version description
version=$(jq -r --arg n "$name" '.[$n].version // "local"' "$INSTALLED_FILE")
# Extract description from file
description=$(grep -A1 '^description:' "$file" 2>/dev/null | head -1 | sed 's/^description: *//' || echo "No description")
printf " โโโ %-15s %-8s %s\n" "$name" "$version" "$description"
((count++))
done
echo
echo "${count} style(s) installed"
}
# Command: update
cmd_update() {
local name="${1:-}"
local registry
registry=$(fetch_registry)
if [[ -n "$name" ]]; then
# Update specific style
update_single "$name" "$registry"
else
# Update all
log_info "Checking for updates..."
echo
for file in "${STYLES_DIR}"/*.md; do
[[ -f "$file" ]] || continue
local style_name
style_name=$(basename "$file" .md)
[[ "$style_name" == .* ]] && continue
update_single "$style_name" "$registry" || true
done
fi
}
update_single() {
local name="$1"
local registry="$2"
local installed_version
installed_version=$(jq -r --arg n "$name" '.[$n].version // "unknown"' "$INSTALLED_FILE")
if [[ "$installed_version" == "unknown" ]]; then
log_warn "${name}: Local style, skipping"
return 0
fi
local latest_version
latest_version=$(echo "$registry" | jq -r --arg n "$name" '
[.styles[] | select(.name == $n)] | sort_by(.version) | last | .version // "N/A"
')
if [[ "$latest_version" == "N/A" ]]; then
log_warn "${name}: Not found in registry"
return 0
fi
if [[ "$installed_version" == "$latest_version" ]]; then
echo "${name}: Up to date (${installed_version})"
return 0
fi
log_info "${name}: ${installed_version} โ ${latest_version} available"
read -rp "Update? [Y/n] " confirm
if [[ "${confirm:-Y}" != [Yy]* ]]; then
return 0
fi
cmd_install "${name}@${latest_version}"
}
# Command: validate
cmd_validate() {
local file="${1:-}"
if [[ -z "$file" || ! -f "$file" ]]; then
log_error "Usage: claude-styles validate <file>"
exit 1
fi
log_info "Validating ${file}..."
echo
local content
content=$(cat "$file")
validate_content "$content"
}
# Validate content helper
validate_content() {
local content="$1"
local errors=0
echo "Frontmatter:"
# Check for frontmatter
if [[ ! "$content" =~ ^---[[:space:]] ]]; then
log_error " โ Missing YAML frontmatter"
((errors++))
else
# Extract frontmatter
local frontmatter
frontmatter=$(echo "$content" | sed -n '/^---$/,/^---$/p' | sed '1d;$d')
# Check name
if echo "$frontmatter" | grep -q '^name:'; then
local name_value
name_value=$(echo "$frontmatter" | grep '^name:' | sed 's/^name: *//')
if [[ "$name_value" =~ ^[a-z0-9-]+$ ]]; then
log_success " โโโ name: ${name_value} โ"
else
log_error " โโโ name: Invalid format (use lowercase, alphanumeric, hyphens)"
((errors++))
fi
else
log_error " โโโ name: MISSING (required)"
((errors++))
fi
# Check version
if echo "$frontmatter" | grep -q '^version:'; then
local version_value
version_value=$(echo "$frontmatter" | grep '^version:' | sed 's/^version: *//')
if [[ "$version_value" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
log_success " โโโ version: ${version_value} โ"
else
log_error " โโโ version: Invalid semver format (use X.Y.Z)"
((errors++))
fi
else
log_warn " โโโ version: Missing (required for registry)"
fi
# Check description
if echo "$frontmatter" | grep -q '^description:'; then
log_success " โโโ description: present โ"
else
log_warn " โโโ description: Missing (recommended)"
fi
# Check keep-coding-instructions
if echo "$frontmatter" | grep -q '^keep-coding-instructions:'; then
local kci_value
kci_value=$(echo "$frontmatter" | grep '^keep-coding-instructions:' | sed 's/^keep-coding-instructions: *//')
if [[ "$kci_value" =~ ^(true|false)$ ]]; then
log_success " โโโ keep-coding-instructions: ${kci_value} โ"
else
log_error " โโโ keep-coding-instructions: Invalid (use true or false)"
((errors++))
fi
else
log_success " โโโ keep-coding-instructions: not set (defaults to true) โ"
fi
fi
echo
echo "Content:"
# Extract body (after second ---)
local body
body=$(echo "$content" | sed -n '/^---$/,/^---$/d;p')
# Check line count
local line_count
line_count=$(echo "$body" | grep -c '[^[:space:]]' || echo "0")
if [[ $line_count -ge 10 ]]; then
log_success " โโโ Line count: ${line_count} (minimum 10) โ"
else
log_error " โโโ Line count: ${line_count} (minimum 10 required)"
((errors++))
fi
# Check for headings
if echo "$body" | grep -q '^#'; then
log_success " โโโ Has headings: yes โ"
else
log_error " โโโ Has headings: no (at least one required)"
((errors++))
fi
# Check for placeholder text
if echo "$body" | grep -iqE '(TODO|XXX|FIXME|placeholder)'; then
log_warn " โโโ Contains placeholder text"
else
log_success " โโโ No placeholder text: yes โ"
fi
echo
if [[ $errors -gt 0 ]]; then
log_error "โ Validation failed with ${errors} error(s)"
return 1
else
log_success "โ
Valid output style! Ready for use or publication."
return 0
fi
}
# Command: publish (placeholder)
cmd_publish() {
local file="${1:-}"
if [[ -z "$file" || ! -f "$file" ]]; then
log_error "Usage: claude-styles publish <file>"
exit 1
fi
log_info "Publishing style..."
# Validate first
if ! cmd_validate "$file"; then
log_error "Style must pass validation before publishing"
exit 1
fi
echo
log_info "To publish your style:"
echo "1. Fork https://github.com/claude-styles/registry"
echo "2. Add your style to the styles/ directory"
echo "3. Update index.json with your style metadata"
echo "4. Submit a pull request"
echo
echo "Contribution guide: https://github.com/claude-styles/registry#contributing"
}
# Main dispatcher
main() {
local cmd="${1:-help}"
shift || true
case "$cmd" in
search) cmd_search "$@" ;;
install) cmd_install "$@" ;;
uninstall) cmd_uninstall "$@" ;;
list) cmd_list "$@" ;;
update) cmd_update "$@" ;;
validate) cmd_validate "$@" ;;
publish) cmd_publish "$@" ;;
help|--help|-h)
echo "claude-styles - Output style package manager for Claude Code"
echo
echo "Usage:"
echo " claude-styles search <query> Search for styles"
echo " claude-styles install <name> Install a style"
echo " claude-styles uninstall <name> Remove a style"
echo " claude-styles list Show installed styles"
echo " claude-styles update [name] Update style(s)"
echo " claude-styles validate <file> Validate a style file"
echo " claude-styles publish <file> Publish to registry"
echo
echo "Examples:"
echo " claude-styles search documentation"
echo " claude-styles install tech-writer"
echo " claude-styles install tech-writer@2.1.0"
echo " claude-styles list"
;;
*)
log_error "Unknown command: $cmd"
echo "Run 'claude-styles help' for usage"
exit 1
;;
esac
}
main "$@"
10.2 Sample Registry Index
Create a sample index.json for testing:
{
"styles": [
{
"name": "tech-writer",
"version": "2.1.0",
"description": "Technical documentation with formal tone",
"author": "@expert_writer",
"url": "https://raw.githubusercontent.com/claude-styles/registry/main/styles/tech-writer/2.1.0.md",
"downloads": 1234,
"rating": 4.8,
"tags": ["documentation", "technical", "formal"],
"created": "2024-06-01T00:00:00Z",
"updated": "2025-01-15T10:30:00Z"
},
{
"name": "code-review",
"version": "1.5.0",
"description": "Systematic code review assistant",
"author": "@review_pro",
"url": "https://raw.githubusercontent.com/claude-styles/registry/main/styles/code-review/1.5.0.md",
"downloads": 892,
"rating": 4.6,
"tags": ["review", "code", "quality"],
"created": "2024-08-15T00:00:00Z",
"updated": "2025-01-10T14:00:00Z"
},
{
"name": "learning",
"version": "1.0.0",
"description": "Educational explanations with analogies",
"author": "@teacher_ai",
"url": "https://raw.githubusercontent.com/claude-styles/registry/main/styles/learning/1.0.0.md",
"downloads": 567,
"rating": 4.5,
"tags": ["learning", "education", "beginner"],
"created": "2024-09-01T00:00:00Z",
"updated": "2024-12-01T09:00:00Z"
}
],
"updated": "2025-01-15T10:30:00Z"
}
10.3 Installation Script
Create an installation script:
#!/usr/bin/env bash
#
# Install claude-styles CLI
#
set -euo pipefail
INSTALL_DIR="${HOME}/.local/bin"
SCRIPT_URL="https://raw.githubusercontent.com/claude-styles/cli/main/claude-styles"
echo "Installing claude-styles..."
# Create install directory
mkdir -p "$INSTALL_DIR"
# Download script
curl -sf "$SCRIPT_URL" -o "${INSTALL_DIR}/claude-styles"
chmod +x "${INSTALL_DIR}/claude-styles"
# Check if in PATH
if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then
echo
echo "Add this to your shell profile:"
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
fi
echo
echo "โ
Installed claude-styles to ${INSTALL_DIR}/claude-styles"
echo
echo "Run 'claude-styles help' to get started"
11. Books That Will Help
| Topic | Book | Chapter/Section |
|---|---|---|
| Package management | โSoftware Engineering at Googleโ by Winters et al. | Ch. 21: Dependency Management |
| Open source patterns | โProducing Open Source Softwareโ by Karl Fogel | Ch. 5: Technical Infrastructure |
| Registry design | npm documentation | Architecture section |
| CLI design | โThe Art of Unix Programmingโ by Eric Raymond | Ch. 10: Command-Line Interface |
| Bash scripting | โThe Linux Command Lineโ by William Shotts | Part 4: Shell Scripts |
12. Common Pitfalls and Solutions
| Pitfall | Symptom | Solution |
|---|---|---|
| No validation | Broken styles get installed | Always validate before install |
| Version conflicts | Old version overwrites new | Track installed versions in metadata |
| Network dependency | Offline use fails | Cache registry index locally |
| No backup | Overwritten styles lost | Backup before replacing |
| Path issues | Script not found | Ensure ~/.local/bin is in PATH |
| jq not installed | Script fails | Check dependencies at start |
13. Self-Assessment Checklist
Understanding Verification
- I can explain how package managers work (registry, metadata, installation)
- I understand semantic versioning and when to bump major/minor/patch
- I can describe what makes a valid output style
- I understand the difference between user and project scope installation
- I can explain the security considerations for user-contributed styles
Implementation Verification
- Search command finds styles by name, description, and tags
- Install command downloads and validates styles
- Uninstall command removes styles and updates tracking
- List command shows installed styles with versions
- Update command checks for and applies updates
- Validate command checks frontmatter and content
Integration Verification
- CLI is installed and accessible from terminal
- Installed styles work with
claude --output-style - Version tracking persists across sessions
- Error messages are helpful and actionable
14. Extensions and Challenges
14.1 Beginner Extensions
- Add
claude-styles info <name>to show detailed style info - Add download count tracking for local installs
- Create colorized output for better readability
14.2 Intermediate Extensions
- Implement local caching of registry index
- Add
--dry-runflag to preview actions - Support multiple registries (like npm scopes)
- Add
claude-styles initto create new style template
14.3 Advanced Extensions
- Build a web UI for browsing styles
- Implement style dependencies (A requires B)
- Add cryptographic signatures for style verification
- Create GitHub Action for style publishing
15. Completion Criteria
Minimum Viable Completion
- CLI with search, install, list commands
- Basic validation of frontmatter
- Local tracking of installed styles
- Works with mock registry data
Full Completion
- All commands implemented (search, install, uninstall, list, update, validate, publish)
- Full validation of frontmatter and content
- Version management with updates
- Conflict detection and backup
- Helpful error messages
Excellence (Going Above and Beyond)
- Actual GitHub registry set up
- Multiple registries support
- Web UI for browsing
- Automated publishing workflow
- Comprehensive test suite
- Documentation for contributors
This guide was expanded from CLAUDE_CODE_MASTERY_40_PROJECTS.md. For the complete learning path, see the README.