Documentation for contributors to Impeccable.
This repository uses a feature-rich source format that transforms into provider-specific formats. We chose "Option A" architecture: maintain full metadata in source files and downgrade for providers with limited support (like Cursor), rather than limiting everyone to the lowest common denominator.
Different providers have different capabilities:
- Claude Code, OpenCode: Full metadata — args, user-invokable, allowed-tools, license, compatibility
- Codex, Agents: Args converted to
argument-hintformat - Gemini: Minimal frontmatter,
{{arg}}placeholders become{{args}} - Cursor, Kiro, Pi: Basic frontmatter (name, description, license/compatibility)
By maintaining rich source files, we preserve maximum functionality where supported while still providing working (if simpler) versions for all providers.
---
name: skill-name
description: What this skill provides
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-invokable(optional): Boolean — iftrue, the skill can be invoked as a slash commandargs(optional): Array of argument objects (for user-invokable skills)name: Argument identifierdescription: What it's forrequired: Boolean (defaults to false)
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: The skill instructions for the LLM.
- 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 cursor/.cursor/skills/{name}/SKILL.md
claude-code/.claude/skills/{name}/SKILL.md
gemini/.gemini/skills/{name}/SKILL.md
codex/.codex/skills/{name}/SKILL.md
agents/.agents/skills/{name}/SKILL.md
kiro/.kiro/skills/{name}/SKILL.md
opencode/.opencode/skills/{name}/SKILL.md
pi/.pi/skills/{name}/SKILL.md
All providers output skills to dist/{provider}/.{config}/skills/{name}/SKILL.md with reference files in subdirectories. They differ in frontmatter fields and argument handling.
- Output:
dist/cursor/.cursor/skills/{name}/SKILL.md - Frontmatter: name, description, license
- Note: Agent Skills require Cursor nightly channel
- Output:
dist/claude-code/.claude/skills/{name}/SKILL.md - Frontmatter: name, description, user-invokable, args, license, compatibility, metadata, allowed-tools
- Preserves
{{arg}}placeholders in body
- Output:
dist/opencode/.opencode/skills/{name}/SKILL.md - Frontmatter: name, description, user-invokable, args, license, compatibility, metadata, allowed-tools
- Same format as Claude Code
- Output:
dist/gemini/.gemini/skills/{name}/SKILL.md - Frontmatter: name, description
- For user-invokable skills: remaining
{{arg}}placeholders become{{args}}
- Output:
dist/codex/.codex/skills/{name}/SKILL.md - Frontmatter: name, description, argument-hint, license
- For user-invokable skills:
{{argname}}→$ARGNAME(uppercase)
- Output:
dist/agents/.agents/skills/{name}/SKILL.md - Frontmatter: name, description, user-invokable, argument-hint
- Args converted to
argument-hintformat (e.g.,<target> [FORMAT=<value>])
- Output:
dist/kiro/.kiro/skills/{name}/SKILL.md - Frontmatter: name, description, license, compatibility, metadata
- Output:
dist/pi/.pi/skills/{name}/SKILL.md - Frontmatter: name, description, license, compatibility, metadata
mkdir source/skills/myskill
touch source/skills/myskill/SKILL.mdAdd frontmatter and content following the format above.
bun run buildThis generates all 8 provider formats automatically.
Test with your provider of choice to ensure it works correctly. Remember that Cursor will have limited functionality.
Commit source files:
git add source/
git commit -m "Add [skill name]"The build system uses a modular architecture under scripts/:
build.js— Main orchestratorlib/utils.js— Shared utilities (frontmatter parsing, file I/O, placeholder replacement)lib/zip.js— ZIP bundle generationlib/transformers/*.js— One file per provider (cursor, claude-code, gemini, codex, agents, kiro, opencode, pi)
parseFrontmatter(): Extracts YAML frontmatter and bodyreadSourceFiles(): Reads all skill directories fromsource/skills/replacePlaceholders(): Substitutes{{model}},{{config_file}}, etc. per providertransformCursor(): Basic frontmatter (name, description, license)transformClaudeCode(): Full metadata with args and allowed-toolstransformGemini(): Minimal frontmatter,{{arg}}→{{args}}transformCodex(): Args → argument-hint,{{arg}}→$ARGNAMEtransformAgents(): Args → argument-hint, user-invokable flagtransformKiro(): Basic frontmatter with license/compatibility/metadatatransformOpenCode(): Full metadata (same as Claude Code)transformPi(): Basic frontmatter with license/compatibility/metadata
- 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
- Cursor Commands
- Cursor Rules
- Cursor Skills
- Claude Code Slash Commands
- Anthropic Skills (Claude Code)
- Gemini CLI Custom Commands
- Gemini CLI Skills
- Codex CLI Slash Commands
- Codex CLI 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)
│ ├── cursor/
│ ├── claude-code/
│ ├── gemini/
│ ├── codex/
│ ├── agents/
│ ├── kiro/
│ ├── opencode/
│ └── pi/
├── scripts/
│ ├── build.js # Main orchestrator
│ └── lib/
│ ├── utils.js # Shared utilities
│ ├── zip.js # ZIP generation
│ └── transformers/ # One file per provider
│ ├── cursor.js
│ ├── claude-code.js
│ ├── gemini.js
│ ├── codex.js
│ ├── agents.js
│ ├── kiro.js
│ ├── opencode.js
│ └── pi.js
├── tests/ # Bun test suite
├── package.json # ESM project config
├── README.md # User documentation
├── DEVELOP.md # This file
└── .gitignore
- Check frontmatter indentation (YAML is indent-sensitive)
- Ensure
---delimiters are on their own lines - Verify colons have spaces after them (
key: value)
- Check the transformer function for your provider in
scripts/lib/transformers/ - 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 provider's documentation (links above)
Open an issue or submit a PR!