1# Developer Guide
2
3Documentation for contributors to Impeccable.
4
5## Architecture
6
7Source skills in `source/skills/` are 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.
8
9For detailed harness capabilities (which frontmatter fields each supports, placeholder systems, directory structures), see [HARNESSES.md](HARNESSES.md).
10
11## Source Format
12
13### Skills (`source/skills/{name}/SKILL.md`)
14
15```yaml
16---
17name: skill-name
18description: What this skill provides
19argument-hint: "[target]"
20user-invocable: true
21license: License info (optional)
22compatibility: Environment requirements (optional)
23---
24
25Your skill instructions here...
26```
27
28**Frontmatter fields** (based on [Agent Skills spec](https://agentskills.io/specification)):
29- `name` (required): Skill identifier (1-64 chars, lowercase/numbers/hyphens)
30- `description` (required): What the skill provides (1-1024 chars)
31- `user-invocable` (optional): Boolean -- if `true`, the skill can be invoked as a slash command
32- `argument-hint` (optional): Hint shown during autocomplete (e.g., `[target]`, `[area (feature, page...)]`)
33- `license` (optional): License/attribution info
34- `compatibility` (optional): Environment requirements (1-500 chars)
35- `metadata` (optional): Arbitrary key-value pairs
36- `allowed-tools` (optional, experimental): Pre-approved tools list
37
38**Body placeholders** (replaced per-provider during build):
39- `{{model}}` -- Provider-specific model name (e.g., "Claude", "Gemini", "GPT")
40- `{{config_file}}` -- Provider-specific config file (e.g., "CLAUDE.md", ".cursorrules")
41- `{{ask_instruction}}` -- How to ask the user for clarification
42- `{{command_prefix}}` -- Slash command prefix (`/` for most, `$` for Codex)
43- `{{available_commands}}` -- Comma-separated list of user-invocable commands
44
45## Building
46
47### Prerequisites
48- Bun (fast JavaScript runtime and package manager)
49- No external dependencies required
50
51### Commands
52
53```bash
54# Build all provider formats
55bun run build
56
57# Clean dist folder
58bun run clean
59
60# Rebuild from scratch
61bun run rebuild
62```
63
64### What Gets Generated
65
66```
67source/ -> dist/
68 skills/{name}/SKILL.md {provider}/{configDir}/skills/{name}/SKILL.md
69```
70
71Each provider gets its own output directory. Two variants are generated per provider: unprefixed and prefixed (with `i-` prefix for skill names).
72
73## Build System Details
74
75The build system uses a factory pattern under `scripts/`:
76
77```
78scripts/
79 build.js # Main orchestrator
80 lib/
81 utils.js # Frontmatter parsing, placeholder replacement, YAML generation
82 zip.js # ZIP bundle generation
83 transformers/
84 factory.js # createTransformer() -- generates transformer functions from config
85 providers.js # PROVIDERS config map -- one entry per provider
86 index.js # Re-exports factory-generated transformer functions
87```
88
89### Adding a New Provider
90
911. Add a placeholder config to `PROVIDER_PLACEHOLDERS` in `scripts/lib/utils.js`:
92 ```javascript
93 'my-provider': {
94 model: 'MyModel',
95 config_file: 'CONFIG.md',
96 ask_instruction: 'ask the user directly to clarify.',
97 command_prefix: '/'
98 }
99 ```
100
1012. Add a provider config to `PROVIDERS` in `scripts/lib/transformers/providers.js`:
102 ```javascript
103 'my-provider': {
104 provider: 'my-provider',
105 configDir: '.my-provider',
106 displayName: 'My Provider',
107 frontmatterFields: ['user-invocable', 'argument-hint', 'license'],
108 }
109 ```
110
1113. Run `bun run build` -- the provider is automatically picked up by the build loop.
112
1134. Update `HARNESSES.md` with the provider's capabilities.
114
115### Provider Config Options
116
117| Field | Description |
118|-------|-------------|
119| `provider` | Key for output directory and placeholder lookup |
120| `configDir` | Dot-directory name (e.g., `.claude`) |
121| `displayName` | Human-readable name for build logs |
122| `frontmatterFields` | Which optional fields to emit (see `factory.js` FIELD_SPECS) |
123| `bodyTransform` | Optional `(body, skill) => body` function for post-processing |
124| `placeholderProvider` | Override which PROVIDER_PLACEHOLDERS key to use (for variants sharing config) |
125
126### Key Functions
127
128- `createTransformer(config)`: Factory that returns a transformer function from a provider config
129- `parseFrontmatter()`: Extracts YAML frontmatter and body from SKILL.md files
130- `readSourceFiles()`: Reads all skill directories from `source/skills/`
131- `replacePlaceholders()`: Substitutes `{{model}}`, `{{config_file}}`, etc. per provider
132- `generateYamlFrontmatter()`: Serializes objects to YAML frontmatter (auto-quotes values starting with `[` or `{`)
133- `prefixSkillReferences()`: Replaces `/skillname` with `/i-skillname` for prefixed variants
134
135## Best Practices
136
137### Skill Writing
138
1391. **Focused scope**: One clear domain per skill
1402. **Clear descriptions**: Make purpose obvious
1413. **Clear instructions**: LLM should understand exactly what to do
1424. **Include examples**: Where they clarify intent
1435. **State constraints**: What NOT to do as clearly as what to do
1446. **Test across providers**: Verify it works in multiple contexts
145
146## Reference Documentation
147
148- [Agent Skills Specification](https://agentskills.io/specification) - Open standard
149- [HARNESSES.md](HARNESSES.md) - Provider capabilities matrix
150- [Cursor Skills](https://cursor.com/docs/context/skills)
151- [Claude Code Skills](https://code.claude.com/docs/en/skills)
152- [Gemini CLI Skills](https://geminicli.com/docs/cli/skills/)
153- [Codex CLI Skills](https://developers.openai.com/codex/skills/)
154- [VS Code Copilot Skills](https://code.visualstudio.com/docs/copilot/customization/agent-skills)
155- [Kiro Skills](https://kiro.dev/docs/skills/)
156- [OpenCode Skills](https://opencode.ai/docs/skills/)
157- [Pi Skills](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/skills.md)
158
159## Repository Structure
160
161```
162impeccable/
163 source/ # Edit these! Source of truth
164 skills/ # Skill definitions
165 frontend-design/
166 SKILL.md
167 reference/*.md # Domain-specific references
168 audit/SKILL.md
169 polish/SKILL.md
170 ...
171 dist/ # Generated output (gitignored)
172 scripts/
173 build.js # Main orchestrator
174 lib/
175 utils.js # Shared utilities
176 zip.js # ZIP generation
177 transformers/
178 factory.js # Config-driven transformer factory
179 providers.js # Provider config map
180 index.js # Re-exports
181 tests/ # Bun test suite
182 HARNESSES.md # Provider capabilities reference
183 DEVELOP.md # This file
184 README.md # User documentation
185```
186
187## Troubleshooting
188
189### Build fails with YAML parsing errors
190- Check frontmatter indentation (YAML is indent-sensitive)
191- Ensure `---` delimiters are on their own lines
192- Values starting with `[` or `{` are auto-quoted; other special YAML chars may need manual quoting
193
194### Output doesn't match expectations
195- Check the provider config in `scripts/lib/transformers/providers.js`
196- Verify source file has correct frontmatter structure
197- Run `bun run rebuild` to ensure clean build
198
199### Provider doesn't recognize the files
200- Check installation path for your provider
201- Verify file naming matches provider requirements
202- Consult [HARNESSES.md](HARNESSES.md) for provider-specific details
203
204## Questions?
205
206Open an issue or submit a PR!