Documentation for contributors to Impeccable.
The skill at skill/ is 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
No-index visual harnesses and internal inspectors live under /labs/<subject>. Use a short subject noun (/labs/live-ui, later /labs/detector), not a second -lab suffix. Stable public references such as /docs and /design-system stay top-level. Keep legacy top-level lab routes working through redirects when a lab moves; migrate existing exceptions when that surface is next changed rather than duplicating the page.
- 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.
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(): Readsskill/SKILL.src.mdplus itsreference/andscripts/siblingsreplacePlaceholders(): Substitutes{{model}},{{config_file}}, etc. per providergenerateYamlFrontmatter(): Serializes objects to YAML frontmatter (auto-quotes values starting with[or{)
bun run test # Default suite — unit + static fixtures (no API keys needed)
bun run test:live-e2e # Opt-in — full-cycle live-mode E2E across framework fixtures (~2 min, needs `npx playwright install chromium` once)
bun run test:skill-behavior # Opt-in — LLM-backed checks that the SKILL.md Setup flow actually drives the agent (~5 min, costs cents, needs `.env`)The skill-behavior suite runs three providers (claude-haiku-4-5, gpt-5.4-mini, gemini-3.1-flash-lite — the cheapest tier of each, every run) with the source skill/SKILL.src.md inlined as the system prompt and a workspace-scoped bash/read/write/list tool set. It then asserts on the tool-call trace, not on free-form output. Use it whenever you edit skill/SKILL.src.md's Setup section, skill/scripts/context.mjs, or any Setup-touching reference (teach.md, document.md, brand.md, product.md, sub-command refs). Per-scenario assertions and the current baseline (21-22/24) live in tests/skill-behavior/README.md. Provider keys live in repo-root .env (gitignored); missing keys skip cleanly.
- 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. For Setup-related edits to
skill/,bun run test:skill-behaviorautomates this across three providers.
- 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
- Qoder Skills
- Mistral Vibe Skills
- Grok Build Skills, Plugins & Marketplaces
- Grok Build Hooks
impeccable/
skill/ # Edit these! Source of truth
SKILL.src.md # Frontmatter, shared design laws, command router
reference/ # One <command>.md per command + domain references
scripts/ # Skill runtime scripts (hooks, context.mjs, etc.)
agents/ # Nested subagent definitions
cli/ # Standalone `impeccable` CLI (npm package)
site/ # impeccable.style (Astro)
extension/ # Chrome extension
functions/ # Cloudflare Pages Functions
plugin/ # Committed Claude Code plugin build output
dist/ # Generated provider 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
docs/
HARNESSES.md # Provider capabilities reference
STYLE.md # Editorial style guide
adr-live-variant-mode.md # Live mode architecture decision record
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 first. If a maintainer approves the direction, offer to follow up with a PR. Regular contributors pbakaus and abdulwahabone may open PRs directly.