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:
- Cursor: No frontmatter or argument support
- Claude Code, Gemini, Codex: Full support for metadata and arguments
By maintaining rich source files, we preserve maximum functionality where supported while still providing working (if simpler) versions for all providers.
---
name: command-name
description: What this command does
args:
- name: argname
description: Argument description
required: false
---
Your command prompt here with {{argname}} placeholders...Frontmatter fields:
name(required): Command identifierdescription(required): What the command doesargs(optional): Array of argument objectsname: Argument identifierdescription: What it's forrequired: Boolean (defaults to false)
Body: The actual prompt. Use {{argname}} for argument placeholders (automatically transformed to provider-specific syntax).
---
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)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/
commands/*.md cursor/commands/*.md (body only)
skills/*.md cursor/skills/*/SKILL.md (Agent Skills standard)
claude-code/commands/*.md (full frontmatter)
claude-code/skills/*/SKILL.md
gemini/commands/*.toml (TOML format)
gemini/GEMINI*.md (modular)
codex/prompts/*.md (custom prompt format)
codex/skills/*/SKILL.md (Agent Skills standard)
- Commands → Body only →
dist/cursor/.cursor/commands/*.md(no frontmatter support) - Skills → Agent Skills standard →
dist/cursor/.cursor/skills/{name}/SKILL.md- Full YAML frontmatter support
- Reference files in skill subdirectories
- Note: Agent Skills require Cursor nightly channel
- Keeps full YAML frontmatter + body
- Commands →
dist/claude-code/commands/*.md - Skills →
dist/claude-code/skills/{name}/SKILL.md
- Commands converted to TOML format →
dist/gemini/commands/*.tomldescriptionandpromptkeys- Arguments converted to
{{args}}(Gemini uses single args string)
- Skills → Modular
GEMINI.{name}.mdfiles - Main
GEMINI.mdimports skill files using@./GEMINI.{name}.mdsyntax- Uses Gemini's native import feature for modular context files
- Commands → Custom prompts with
argument-hint→dist/codex/.codex/prompts/*.md- Frontmatter uses
descriptionandargument-hint(notargsarray) - Placeholders transformed from
{{argname}}to$ARGNAME(uppercase) - Invoked as
/prompts:<name>
- Frontmatter uses
- Skills → Agent Skills standard →
dist/codex/.codex/skills/{name}/SKILL.md- Uses same SKILL.md format as Claude Code
- Reference files in subdirectories
- Skills → Agent Skills standard →
dist/pi/.pi/skills/{name}/SKILL.md- Standard frontmatter: name, description, license, compatibility, metadata
- Reference files in skill subdirectories
For a command:
# Create source/commands/mycommand.md
touch source/commands/mycommand.mdAdd frontmatter and content following the format above.
For a skill:
# Create source/skills/myskill.md
touch source/skills/myskill.mdAdd frontmatter and content following the format above.
bun run buildThis generates all 4 provider formats automatically.
Test with your provider of choice to ensure it works correctly. Remember that Cursor will have limited functionality.
Commit both source and dist files:
git add source/ dist/
git commit -m "Add [command/skill name]"Important: The dist/ directory is committed intentionally so end users can use files without building.
The build system (scripts/build.js) is a single ~170-line Node.js script with:
- Custom YAML frontmatter parser (no dependencies)
- Provider-specific transformation functions
- Automatic directory management
- Zero external dependencies (pure Node.js)
parseFrontmatter(): Extracts YAML frontmatter and bodyreadSourceFiles(): Recursively reads source filestransformCursor(): Strips frontmatter for CursortransformClaudeCode(): Keeps full formattransformGemini(): Converts to TOML + modular skillstransformCodex(): Full format + modular skills
- Clear descriptions: Make purpose obvious
- Meaningful argument names: Use descriptive names
- Flexible prompts: Write prompts that work even without argument substitution (for Cursor compatibility)
- Test across providers: Verify it works in multiple contexts
- Focused scope: One clear domain per skill
- 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
- 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
│ ├── commands/ # Command definitions
│ │ └── normalize.md
│ └── skills/ # Skill definitions
│ └── frontend-design.md
├── dist/ # Generated (committed for users)
│ ├── cursor/
│ ├── claude-code/
│ ├── gemini/
│ ├── codex/
│ ├── agents/
│ ├── kiro/
│ ├── opencode/
│ └── pi/
├── scripts/
│ └── build.js # Build system (~170 lines, zero deps)
├── 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/build.js - Verify source file has correct frontmatter structure
- Run
npm 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!