Skill Builder
Build, update, and validate Claude Code skills following best practices for public distribution.
Core Principle: Generalization for Public Users
CRITICAL: Skills in ~/.claude/skills/ may be shared publicly. Never include:
| ❌ Never Include | ✅ Use Instead |
|---|---|
| Hardcoded project names | Environment variables |
| Specific UUIDs/IDs | process.env.VAR_NAME |
| Personal API endpoints | Configurable URLs |
| Company-specific logic | Generic patterns |
| Internal team references | Generic examples |
Example: Linear Skill Refactoring
Before (project-specific):
export const INITIATIVES = {
SKILLSMITH: '5e1cebfe-f4bb-42c1-988d-af792fc4253b'
}
export async function linkAllSkillsmithProjects() { ... }
After (generalized):
export const DEFAULT_INITIATIVE_ID = process.env.LINEAR_DEFAULT_INITIATIVE_ID || ''
export async function linkProjectsToInitiative(initiativeId: string, filter?) { ... }
Behavioral Classification (ADR-025)
Every skill must declare its behavioral type. This determines how the skill interacts with users.
1. Autonomous Execution
Directive: EXECUTE, DON'T ASK
Skills that follow a prescribed workflow automatically. No permission-seeking.
| Use For | Examples |
|---|---|
| Enforcement/compliance | governance, docker-enforce |
| Automated fixes | lint-fix, format |
| CI/CD integrations | deploy, release |
2. Guided Decision
Directive: ASK, THEN EXECUTE
Skills that ask structured questions upfront, then execute based on decisions.
| Use For | Examples |
|---|---|
| Planning/architecture | wave-planner, mcp-decision-helper |
| Configuration wizards | init, setup |
| Template generators | skill-builder |
3. Interactive Exploration
Directive: ASK THROUGHOUT
Skills with ongoing dialogue. The conversation IS the value.
| Use For | Examples |
|---|---|
| Research/exploration | researcher |
| Browser automation | dev-browser |
| Debugging sessions | debugger |
4. Configurable Enforcement
Directive: USER-CONFIGURED
Skills that adapt behavior based on project/user configuration.
| Use For | Examples |
|---|---|
| Security tools with severity levels | varlock, security-auditor |
| Linting with configurable strictness | eslint-wrapper |
| Environment-dependent workflows | ci-doctor |
Classification Decision Tree
Does the skill need user input to work?
│
├─ NO → Autonomous Execution
│
└─ YES → Is input needed throughout, or just upfront?
│
├─ UPFRONT → Guided Decision
│
└─ THROUGHOUT → Interactive Exploration
Exception: If behavior depends on config → Configurable Enforcement
Skill Creation Checklist
1. Structure Validation
skill-name/
├── SKILL.md # Required: Core instructions
├── README.md # Required: Human-readable docs and install instructions
├── CHANGELOG.md # Required: Version history in Keep a Changelog format
├── references/ # Optional: Detailed docs
├── scripts/ # Optional: Utility scripts
├── hooks/ # Optional: Pre/post command hooks
└── examples/ # Optional: Working examples
README.md must include: problem statement, install command (skillsmith install <author>/<name>), usage examples, contents table, requirements.
CHANGELOG.md must include: ## [X.Y.Z] - YYYY-MM-DD entry for every version with Added/Changed/Fixed sections.
2. SKILL.md Requirements
Frontmatter (required):
---
name: Skill Name
description: This skill should be used when the user asks to "phrase 1", "phrase 2", "phrase 3". Be specific with trigger phrases.
version: 1.0.0
---
Behavioral Classification (required in body):
Every skill MUST include a Behavioral Classification section immediately after the title.
## Behavioral Classification
**Type**: [Autonomous Execution | Guided Decision | Interactive Exploration | Configurable Enforcement]
**Directive**: [EXECUTE, DON'T ASK | ASK, THEN EXECUTE | ASK THROUGHOUT | USER-CONFIGURED]
[Brief description of how the skill interacts with users]
Body requirements:
- Use imperative form ("Configure the server", not "You should configure")
- Keep under 2,000 words (move details to references/)
- Reference all bundled resources
- No project-specific details
3. Generalization Checklist
Before publishing or committing any skill:
- Behavioral classification declared: Type and directive documented
- No hardcoded IDs: UUIDs, project IDs, initiative IDs → environment variables
- No specific names: Project names, company names → generic examples
- No personal URLs: API endpoints, webhooks → configurable via env vars
- No internal references: Team names, internal docs → generic documentation
- Environment variables documented: All required env vars listed
- Generic examples: Examples use placeholder values like
<your-uuid>
3.1 Documentation Generalization (MANDATORY)
CRITICAL: ALL documentation files (README.md, references/, examples/, lessons-learned.md) MUST be fully generalized. This is non-negotiable for public skills.
What to Generalize in Documentation
| ❌ Project-Specific | ✅ Generic Replacement |
|---|---|
| "Skillsmith" | "[Project Name]" or "your project" |
| "SMI-1234" (Linear issues) | "[ISSUE-ID]" or "[Tracking Issue]" |
| "Apache-2.0 to Elastic License 2.0" | "[Old License] to [New License]" |
| "ADR-013", "ADR-017" | "ADR-XXX", "ADR-YYY" |
| Specific file paths from a project | Generic paths like "docs/adr/*.md" |
| Company names (Smith Horn Group, etc.) | "[Your Company]" or omit entirely |
| Real dates tied to a project | "[Date]" or "[Month Year]" |
Case Studies and Examples
When including case studies or lessons learned:
# ❌ BAD - Project-specific case study
## Case Study: Skillsmith License Migration (January 2026)
After migrating Skillsmith from Apache-2.0 to Elastic License 2.0...
Created Linear issue SMI-1369...
# ✅ GOOD - Generalized case study
## Case Study: License Migration (Generic Example)
After migrating a project from an open-source license (e.g., Apache-2.0, MIT)
to a source-available license (e.g., Elastic License 2.0, BSL)...
Created tracking issue [ISSUE-ID]...
Templates Must Use Placeholders
All templates in a skill must use generic placeholders:
# ❌ BAD - Specific project in template
> **Linear Issue:** SMI-XXXX (to be created)
> See [ADR-013](../adr/013-open-core-licensing.md)
# ✅ GOOD - Generic placeholders
> **Tracking Issue:** [ISSUE-ID] (to be created)
> See [ADR-XXX](../adr/XXX.md)
Automatic Generalization Check
Before publishing ANY skill, run:
# Search for common project-specific patterns
grep -ri "skillsmith\|smi-[0-9]\|smith.horn" skill-name/
grep -ri "lin_api_\|api_key.*=" skill-name/ # Exposed secrets
If ANY matches are found, the skill is NOT ready for publishing.
4. Varlock for Secrets Management
CRITICAL: All skills handling secrets MUST use Varlock to prevent exposure.
Required Files
skill-name/
├── .env.schema # Variable definitions with @sensitive annotations (commit)
├── .env.example # Template with placeholders (commit)
└── .env # Actual secrets (NEVER commit)
.env.schema Format
# @type=string(startsWith=lin_api_) @required @sensitive
LINEAR_API_KEY=
# @type=string @optional
LINEAR_DEFAULT_INITIATIVE_ID=
Safe Commands (Always Use)
varlock load # Validate (masked output)
varlock run -- npx tsx scripts/my.ts # Run with secrets injected
Unsafe Commands (NEVER Use)
echo $API_KEY # ❌ Exposes to Claude's context
cat .env