Skip to content

Provider Output Contract

Status: Stable Spec Version: 1 Last Updated: 2026-03-20

This document specifies the contract that every provider driver MUST implement. A provider driver transforms resolved skills into the native configuration format for a specific AI tool.

1. Interface

Every provider driver MUST implement the following interface:

typescript
interface ProviderDriver {
  /**
   * Provider metadata.
   */
  readonly name: string;     // Human-readable name (e.g., "Claude")
  readonly slug: string;     // Machine identifier (e.g., "claude")

  /**
   * Generate output files from resolved skills.
   *
   * MUST be a pure function — no side effects, no file I/O, no network calls.
   * All file writing is handled by the sync orchestrator.
   *
   * @param skills - Array of resolved skills (includes expanded, templates substituted)
   * @param projectPath - Absolute path to the project root
   * @returns Array of file outputs to write
   */
  generate(skills: ResolvedSkill[], projectPath: string): FileOutput[];
}

2. Input: ResolvedSkill

Each skill passed to generate() has already been through include resolution and template variable substitution. The driver receives the final content ready for output.

typescript
interface ResolvedSkill {
  slug: string;
  name: string;
  description: string | null;
  body: string;              // Resolved body (includes expanded, templates substituted)
  category: string;
  skill_type: string | null;
  gotchas: string | null;
  tags: string[];
  conditions: {
    file_patterns?: string[];
    path_prefixes?: string[];
  } | null;
}

Drivers MUST NOT perform include resolution or template substitution — that is the orchestrator's responsibility.

3. Output: FileOutput

typescript
interface FileOutput {
  /** Absolute path where the file should be written. */
  path: string;
  /** File content as a UTF-8 string. */
  content: string;
}

The sync orchestrator handles all file I/O: creating directories, writing files, and cleaning up stale files. Drivers MUST only return the desired file state.

4. Built-in Provider Specifications

4.1 Claude

PropertyValue
Slugclaude
Output.claude/CLAUDE.md
FormatSingle file. Each skill as an H2 heading followed by its body.

Output structure:

markdown
# CLAUDE.md

## {skill.name}

{skill.body}

---

## {skill.name}

{skill.body}

---

Skills with conditions.file_patterns SHOULD include an "Applies to" note:

markdown
> **Applies to:** `*.py, tests/**`

Skills with gotchas SHOULD append a ### Common Gotchas subsection.

4.2 Cursor

PropertyValue
Slugcursor
Output.cursor/rules/{slug}.mdc (one file per skill)
FormatMDC format with YAML frontmatter.

Output structure per file:

markdown
---
description: {skill.description}
alwaysApply: true
globs: ["*.py"]     # only if conditions.file_patterns is set
---

{skill.body}
  • alwaysApply MUST be true when the skill has no conditions, false otherwise.
  • globs MUST be set only when conditions.file_patterns is non-empty.
  • Tags SHOULD be included in frontmatter if present.

4.3 GitHub Copilot

PropertyValue
Slugcopilot
Output.github/copilot-instructions.md
FormatSingle file. Each skill as an H2 heading. Same structure as Claude.

4.4 Windsurf

PropertyValue
Slugwindsurf
Output.windsurf/rules/{slug}.md (one file per skill)
FormatPlain Markdown, one file per skill.

Output structure per file:

markdown
# {skill.name}

{skill.body}

4.5 Cline

PropertyValue
Slugcline
Output.clinerules
FormatSingle flat file. Each skill as an H2 heading.

Output structure:

markdown
## {skill.name}

{skill.body}

---

## {skill.name}

{skill.body}

4.6 OpenAI

PropertyValue
Slugopenai
Output.openai/instructions.md
FormatSingle file. Each skill as an H2 heading. Same structure as Claude.

5. Stale File Cleanup

When syncing, the orchestrator MUST:

  1. Call generate() to get the proposed file list.
  2. Compare against existing provider files on disk.
  3. Delete any existing provider files that are NOT in the proposed list (stale files from renamed/deleted skills).

For multi-file providers (Cursor, Windsurf), this means removing .mdc or .md files that no longer correspond to a skill.

For single-file providers (Claude, Copilot, Cline, OpenAI), the file is simply overwritten.

6. Provider Registration

Built-in providers are registered automatically. Custom providers MAY be registered via manifest.json:

json
{
  "providers": ["claude", "cursor", "./providers/my-custom-provider.js"]
}

Paths starting with ./ are resolved relative to the .skillr/ directory. Custom providers MUST export an object conforming to the ProviderDriver interface.

Released under the MIT License.