Documentation for contributors to Impeccable.
Source skills in source/skills/ are transformed into provider-specific formats by a config-driven factory. Each provider is defined as a config object in scripts/lib/transformers/providers.js -- adding a new provider requires only a new config entry.
For detailed harness capabilities (which frontmatter fields each supports, placeholder systems, directory structures), see HARNESSES.md.
---
name: skill-name
description: What this skill provides
argument-hint: "[target]"
user-invocable: true
license: License info (optional)
compatibility: Environment requirements (optional)
---
Your skill instructions here...Frontmatter fields (based on Agent Skills spec):
name(required): Skill identifier (1-64 chars, lowercase/numbers/hyphens)description(required): What the skill provides (1-1024 chars)user-invocable(optional): Boolean -- iftrue, the skill can be invoked as a slash commandargument-hint(optional): Hint shown during autocomplete (e.g.,[target],[area (feature, page...)])license(optional): License/attribution infocompatibility(optional): Environment requirements (1-500 chars)metadata(optional): Arbitrary key-value pairsallowed-tools(optional, experimental): Pre-approved tools list
Body placeholders (replaced per-provider during build):
{{model}}-- Provider-specific model name (e.g., "Claude", "Gemini", "GPT"){{config_file}}-- Provider-specific config file (e.g., "CLAUDE.md", ".cursorrules"){{ask_instruction}}-- How to ask the user for clarification{{command_prefix}}-- Slash command prefix (/for most,$for Codex){{available_commands}}-- Comma-separated list of user-invocable commands
- Bun (fast JavaScript runtime and package manager)
- No external dependencies required
# Build all provider formats
bun run build
# Clean dist folder
bun run clean
# Rebuild from scratch
bun run rebuildsource/ -> dist/
skills/{name}/SKILL.md {provider}/{configDir}/skills/{name}/SKILL.md
Each provider gets its own output directory. Two variants are generated per provider: unprefixed and prefixed (with i- prefix for skill names).
The build system uses a factory pattern under scripts/:
scripts/
build.js # Main orchestrator
lib/
utils.js # Frontmatter parsing, placeholder replacement, YAML generation
zip.js # ZIP bundle generation
transformers/
factory.js # createTransformer() -- generates transformer functions from config
providers.js # PROVIDERS config map -- one entry per provider
index.js # Re-exports factory-generated transformer functions
-
Add a placeholder config to
PROVIDER_PLACEHOLDERSinscripts/lib/utils.js:'my-provider': { model: 'MyModel', config_file: 'CONFIG.md', ask_instruction: 'ask the user directly to clarify.', command_prefix: '/' }
-
Add a provider config to
PROVIDERSinscripts/lib/transformers/providers.js:'my-provider': { provider: 'my-provider', configDir: '.my-provider', displayName: 'My Provider', frontmatterFields: ['user-invocable', 'argument-hint', 'license'], }
-
Run
bun run build-- the provider is automatically picked up by the build loop. -
Update
HARNESSES.mdwith the provider's capabilities.
| Field | Description |
|---|---|
provider |
Key for output directory and placeholder lookup |
configDir |
Dot-directory name (e.g., .claude) |
displayName |
Human-readable name for build logs |
frontmatterFields |
Which optional fields to emit (see factory.js FIELD_SPECS) |
bodyTransform |
Optional (body, skill) => body function for post-processing |
placeholderProvider |
Override which PROVIDER_PLACEHOLDERS key to use (for variants sharing config) |
createTransformer(config): Factory that returns a transformer function from a provider configparseFrontmatter(): Extracts YAML frontmatter and body from SKILL.md filesreadSourceFiles(): Reads all skill directories fromsource/skills/replacePlaceholders(): Substitutes{{model}},{{config_file}}, etc. per providergenerateYamlFrontmatter(): Serializes objects to YAML frontmatter (auto-quotes values starting with[or{)prefixSkillReferences(): Replaces/skillnamewith/i-skillnamefor prefixed variants
- Focused scope: One clear domain per skill
- Clear descriptions: Make purpose obvious
- Clear instructions: LLM should understand exactly what to do
- Include examples: Where they clarify intent
- State constraints: What NOT to do as clearly as what to do
- Test across providers: Verify it works in multiple contexts
- Agent Skills Specification - Open standard
- HARNESSES.md - Provider capabilities matrix
- Cursor Skills
- Claude Code Skills
- Gemini CLI Skills
- Codex CLI Skills
- VS Code Copilot Skills
- Kiro Skills
- OpenCode Skills
- Pi Skills
impeccable/
source/ # Edit these! Source of truth
skills/ # Skill definitions
frontend-design/
SKILL.md
reference/*.md # Domain-specific references
audit/SKILL.md
polish/SKILL.md
...
dist/ # Generated output (gitignored)
scripts/
build.js # Main orchestrator
lib/
utils.js # Shared utilities
zip.js # ZIP generation
transformers/
factory.js # Config-driven transformer factory
providers.js # Provider config map
index.js # Re-exports
tests/ # Bun test suite
HARNESSES.md # Provider capabilities reference
DEVELOP.md # This file
README.md # User documentation
- Check frontmatter indentation (YAML is indent-sensitive)
- Ensure
---delimiters are on their own lines - Values starting with
[or{are auto-quoted; other special YAML chars may need manual quoting
- Check the provider config in
scripts/lib/transformers/providers.js - Verify source file has correct frontmatter structure
- Run
bun run rebuildto ensure clean build
- Check installation path for your provider
- Verify file naming matches provider requirements
- Consult HARNESSES.md for provider-specific details
Open an issue or submit a PR!