The Adapter Pattern
How SpecSafe translates one set of canonical skills into 8 different AI tool formats.
The Adapter Pattern
SpecSafe supports 8 AI coding tools without maintaining 8 copies of every skill. It does this through an adapter pattern: one canonical skill definition, many output formats.
Canonical Skills
All skills live in canonical/skills/ as Markdown files with YAML frontmatter. Each file defines a single skill: its name, persona, trigger conditions, and full behavioral instructions.
This is the single source of truth. When a skill is updated, the change propagates to every tool on the next install.
The ToolAdapter Interface
Each supported tool has an adapter that implements the ToolAdapter interface with four methods:
| Method | Purpose |
|---|---|
name | Machine identifier for the tool (e.g., claude-code) |
displayName | Human-readable name (e.g., Claude Code) |
detect() | Check whether this tool is configured in the current project |
generate() | Transform canonical skills into tool-specific output files |
Adding support for a new AI tool means writing one adapter. The adapter reads the canonical skill format and writes whatever files the target tool expects.
The Install Flow
When you run specsafe install <tool-name>, this is what happens:
canonical/skills/*.md
|
v
Loader (reads and parses canonical Markdown)
|
v
Registry (finds the matching adapter)
|
v
Adapter (transforms to tool-specific format)
|
v
Output files written to projectFor a Tier 1 tool like Claude Code, the output is individual skill files:
canonical/skills/specsafe-brainstorm.md --> .claude/skills/specsafe-brainstorm/SKILL.md
canonical/skills/specsafe-prd.md --> .claude/skills/specsafe-prd/SKILL.md
canonical/skills/specsafe-test.md --> .claude/skills/specsafe-test/SKILL.md
...For a Tier 2 tool like Aider, the output is a single combined file:
canonical/skills/*.md --> CONVENTIONS.md (all skills merged)Why This Matters
- One update, all tools. Fix a skill once and every tool gets the fix.
- Low cost to add tools. A new adapter is typically under 100 lines of code.
- Consistent behavior. Every tool gets the same skill logic, adapted to its native format.
- No drift. There is no way for tool-specific copies to diverge from the canonical source.
Adding a New Adapter
To support a new AI coding tool:
- Create a new adapter class that implements
ToolAdapter - Implement
detect()to identify when the tool is present in a project - Implement
generate()to transform canonical skills into the tool's expected format - Register the adapter in the tool registry
The loader handles parsing. The adapter only needs to know the output format.