How Impeccable's Build System Transforms Source Skills into Provider-Specific Formats

Impeccable's build system parses YAML-fronted skill files from source/skills/ and routes them through provider-specific transformers that rewrite front-matter, replace placeholder tokens, and emit compatible files for Cursor, Claude Code, Gemini, Codex, and other AI tools into dist/.

The pbakaus/impeccable repository maintains a single source of truth for design skills in source/skills/, then uses a Node.js-based build pipeline to generate provider-specific distributions. This architecture allows the project to support six different AI coding tools from one unified content directory, ensuring consistency while respecting each platform's unique file format requirements.

The Build Pipeline: From Source Files to Provider Bundles

The transformation process begins when you run bun run build (defined in scripts/build.js). The pipeline executes in three distinct phases: ingestion, transformation, and assembly.

Step 1: Ingesting Source Skills

The build script first calls readSourceFiles() from scripts/lib/utils.js (lines 10-62) to walk the source/skills/ directory. For every SKILL.md file encountered, the system parses the YAML front-matter using parseFrontmatter() and extracts the markdown body.

Each skill object contains:

  • name: The skill identifier
  • description: Human-readable summary
  • userInvokable: Boolean flag for interactive skills
  • args: Parameter definitions for dynamic content
  • body: The markdown instruction content
  • references: Array of associated files in reference/*.md

The system also loads design patterns via readPatterns() (lines 92-122) from the frontend-design skill, extracting "DO:" and "DON'T:" items for potential transformer consumption.

Step 2: Provider-Specific Transformation

With the skill array populated, scripts/build.js (lines 90-104) iterates through six provider transformers: transformCursor, transformClaudeCode, transformGemini, transformCodex, transformAgents, and transformKiro. Each transformer executes twice—once with normal names and once with the optional i- prefix to prevent naming collisions.

Every transformer in scripts/lib/transformers/*.js performs four critical operations:

  1. Creates a clean output directory (e.g., dist/cursor/)
  2. Rewrites front-matter to match provider specifications
  3. Replaces placeholder tokens ({{model}}, {{available_commands}}, {{arg}}) with provider-specific syntax
  4. Copies reference files bundled alongside the skill

Step 3: Universal Assembly and Distribution

After all transformers complete, assembleUniversal() (lines 31-59 of scripts/build.js) merges every provider folder into dist/universal/, creating a tool-agnostic bundle. The script then generates ZIP archives via createAllZips and emits static API JSON for the documentation website.

How Provider Transformers Rewrite Skills

Each transformer implements provider-specific logic while maintaining the core skill content. The differences manifest in front-matter handling, placeholder syntax, and file organization.

Front-Matter Adaptation

Providers accept different metadata fields. Cursor (scripts/lib/transformers/cursor.js, lines 15-43) strips all front-matter except name and description, while Claude Code (scripts/lib/transformers/claude-code.js, lines 32-48) preserves the full YAML including user-invokable: true. Gemini (scripts/lib/transformers/gemini.js, lines 38-45) converts skills to TOML-compatible headers but limits custom keys, collapsing remaining arguments into a single {{args}} string for user-invokable skills.

Placeholder Token Replacement

The system defines provider-specific dictionaries mapping generic tokens to platform syntax. For example, {{ask_instruction}} transforms differently across providers:

  • Cursor: "ask the user directly to clarify what you cannot infer"
  • Claude Code: "STOP and call the AskUserQuestionTool to clarify"
  • Codex: "$ASK_INSTRUCTION" (via argument-hint front-matter key)

Codex (scripts/lib/transformers/codex.js, lines 33-56) uniquely creates an argument-hint line from defined args, converting placeholders into shell-style variables.

Reference File Bundling

When a skill directory contains reference/*.md files, each transformer copies these alongside the generated SKILL.md. This ensures comprehensive context travels with the skill regardless of target platform.

Code Examples: Source to Output Transformation

Consider the teach-impeccable skill, which gathers design context from users. Here is how the source transforms across three major providers.

Source Definition

Located at source/skills/teach-impeccable/SKILL.md:

---
name: teach-impeccable
description: One-time setup that gathers design context for your project
user-invokable: true
---

Gather design context for this project, then persist it
{{ask_instruction}} Focus only on what you couldn't infer

Cursor Output

Generated in dist/cursor/.cursor/skills/teach-impeccable/SKILL.md:

---
name: teach-impeccable
description: One-time setup that gathers design context for your project
---

Gather design context for this project, then persist it
ask the user directly to clarify what you cannot infer. Focus only on what you couldn't infer

The Cursor transformer removes unsupported front-matter keys and substitutes the placeholder using PROVIDER_PLACEHOLDERS['cursor'].

Claude Code Output

Generated in dist/claude-code/.claude/skills/teach-impeccable/SKILL.md:

---
name: teach-impeccable
description: One-time setup that gathers design context for your project
user-invokable: true
---

Gather design context for this project, then persist it
STOP and call the AskUserQuestionQuestionTool to clarify. Focus only on what you couldn't infer

Claude Code preserves the user-invokable flag and uses its native tool-calling syntax for the placeholder replacement.

Codex Output

Generated in dist/codex/.codex/skills/teach-impeccable/SKILL.md:

---
name: teach-impeccable
description: One-time setup that gathers design context for your project
argument-hint: <ask_instruction>
---

Gather design context for this project, then persist it
STOP and call the AskUserQuestionTool to clarify. Focus only on what you couldn't infer

Codex introduces the argument-hint key to define CLI-style arguments while maintaining the same instructional body.

Key Implementation Files

Understanding the transformation architecture requires familiarity with these specific files:

Summary

  • Single Source Directory: All skills live in source/skills/ as SKILL.md files with YAML front-matter, creating a maintainable single source of truth.
  • Provider Transformer Architecture: Six distinct transformers in scripts/lib/transformers/ handle the conversion logic for Cursor, Claude Code, Gemini, Codex, Agents, and Kiro.
  • Front-Matter Normalization: Each provider receives only supported metadata keys—Cursor strips extras while Claude Code preserves the full schema.
  • Placeholder Substitution: Generic tokens like {{ask_instruction}} map to provider-specific syntax during the build process.
  • Universal Bundle Assembly: The assembleUniversal() function creates dist/universal/ containing all provider formats for tool-agnostic distribution.

Frequently Asked Questions

How does Impeccable handle unsupported front-matter keys for different providers?

Each provider transformer explicitly filters the source skill's metadata. In scripts/lib/transformers/cursor.js, the code constructs a minimal object containing only name and description before serializing to YAML, while scripts/lib/transformers/claude-code.js passes through the entire front-matter object including user-invokable and custom arguments.

Can I add a new AI tool provider to the build system?

Yes. Create a new file in scripts/lib/transformers/ following the pattern of existing transformers (exporting a default function that accepts skills, outputDir, and usePrefix parameters), then import and invoke it in scripts/build.js alongside the existing six transformers. The utility functions in scripts/lib/utils.js handle the heavy lifting of file I/O and front-matter generation.

What happens to skill references during the transformation?

When a skill directory contains reference/*.md files, each transformer copies these files into the provider-specific output directory alongside the generated SKILL.md. This occurs in the final stage of each transformer's execution loop, ensuring comprehensive documentation travels with the skill regardless of target platform.

Why does the build system create both prefixed and non-prefixed versions?

The optional i- prefix (controlled by the usePrefix parameter) prevents naming collisions when users install multiple skill packs or when skill names conflict with built-in provider commands. Running each transformer twice—once with usePrefix: false and once with usePrefix: true—generates both variants in separate output structures.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →