Files
pbakaus_impeccable/DEVELOP.md
T
GlacierPhonk 8d4f65f351 docs: update DEVELOP.md to reflect current architecture
The contributor guide had fallen behind the codebase in several ways:

- Documented source/commands/ which no longer exists (skills-only now)
- Only described 4 providers (Cursor, Claude Code, Gemini, Codex) —
  added Agents, Kiro, OpenCode, Pi
- Cursor described as "no frontmatter support" but it now uses Agent
  Skills with YAML frontmatter
- "What Gets Generated" diagram showed old command-based output paths
- Build system described as "single ~170-line script" but is now modular
  (scripts/lib/transformers/*.js)
- Referenced dist/ as committed but it's now gitignored
- Key Functions list missing 4 transformer functions
- Source Format missing user-invokable and args fields
- Referenced npm instead of bun in troubleshooting
2026-03-14 22:04:52 +01:00

9.7 KiB

Developer Guide

Documentation for contributors to Impeccable.

Architecture

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.

Why This Approach?

Different providers have different capabilities:

  • Claude Code, OpenCode: Full metadata — args, user-invokable, allowed-tools, license, compatibility
  • Codex, Agents: Args converted to argument-hint format
  • 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.

Source Format

Skills (source/skills/{name}/SKILL.md)

---
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 — if true, the skill can be invoked as a slash command
  • args (optional): Array of argument objects (for user-invokable skills)
    • name: Argument identifier
    • description: What it's for
    • required: Boolean (defaults to false)
  • license (optional): License/attribution info
  • compatibility (optional): Environment requirements (1-500 chars)
  • metadata (optional): Arbitrary key-value pairs
  • allowed-tools (optional, experimental): Pre-approved tools list

Body: The skill instructions for the LLM.

Building

Prerequisites

  • Bun (fast JavaScript runtime and package manager)
  • No external dependencies required

Commands

# Build all provider formats
bun run build

# Clean dist folder
bun run clean

# Rebuild from scratch
bun run rebuild

What Gets Generated

source/                          → 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

Provider Transformations

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.

Cursor

  • 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

Gemini CLI

  • Output: dist/gemini/.gemini/skills/{name}/SKILL.md
  • Frontmatter: name, description
  • For user-invokable skills: remaining {{arg}} placeholders become {{args}}

Codex CLI

  • Output: dist/codex/.codex/skills/{name}/SKILL.md
  • Frontmatter: name, description, argument-hint, license
  • For user-invokable skills: {{argname}}$ARGNAME (uppercase)

Agents (VS Code Copilot, Antigravity)

  • Output: dist/agents/.agents/skills/{name}/SKILL.md
  • Frontmatter: name, description, user-invokable, argument-hint
  • Args converted to argument-hint format (e.g., <target> [FORMAT=<value>])

Kiro

  • Output: dist/kiro/.kiro/skills/{name}/SKILL.md
  • Frontmatter: name, description, license, compatibility, metadata

Pi

  • Output: dist/pi/.pi/skills/{name}/SKILL.md
  • Frontmatter: name, description, license, compatibility, metadata

Adding New Content

1. Create Source File

mkdir source/skills/myskill
touch source/skills/myskill/SKILL.md

Add frontmatter and content following the format above.

2. Build

bun run build

This generates all 8 provider formats automatically.

3. Test

Test with your provider of choice to ensure it works correctly. Remember that Cursor will have limited functionality.

4. Commit

Commit source files:

git add source/
git commit -m "Add [skill name]"

Build System Details

The build system uses a modular architecture under scripts/:

  • build.js — Main orchestrator
  • lib/utils.js — Shared utilities (frontmatter parsing, file I/O, placeholder replacement)
  • lib/zip.js — ZIP bundle generation
  • lib/transformers/*.js — One file per provider (cursor, claude-code, gemini, codex, agents, kiro, opencode, pi)

Key Functions

  • parseFrontmatter(): Extracts YAML frontmatter and body
  • readSourceFiles(): Reads all skill directories from source/skills/
  • replacePlaceholders(): Substitutes {{model}}, {{config_file}}, etc. per provider
  • transformCursor(): Basic frontmatter (name, description, license)
  • transformClaudeCode(): Full metadata with args and allowed-tools
  • transformGemini(): Minimal frontmatter, {{arg}}{{args}}
  • transformCodex(): Args → argument-hint, {{arg}}$ARGNAME
  • transformAgents(): Args → argument-hint, user-invokable flag
  • transformKiro(): Basic frontmatter with license/compatibility/metadata
  • transformOpenCode(): Full metadata (same as Claude Code)
  • transformPi(): Basic frontmatter with license/compatibility/metadata

Best Practices

Skill Writing

  1. Focused scope: One clear domain per skill
  2. Clear descriptions: Make purpose obvious
  3. Clear instructions: LLM should understand exactly what to do
  4. Include examples: Where they clarify intent
  5. State constraints: What NOT to do as clearly as what to do
  6. Test across providers: Verify it works in multiple contexts

Reference Documentation

Repository Structure

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

Troubleshooting

Build fails with YAML parsing errors

  • Check frontmatter indentation (YAML is indent-sensitive)
  • Ensure --- delimiters are on their own lines
  • Verify colons have spaces after them (key: value)

Output doesn't match expectations

  • Check the transformer function for your provider in scripts/lib/transformers/
  • Verify source file has correct frontmatter structure
  • Run bun run rebuild to ensure clean build

Provider doesn't recognize the files

  • Check installation path for your provider
  • Verify file naming matches provider requirements
  • Consult provider's documentation (links above)

Questions?

Open an issue or submit a PR!