# How to Add a New Target Provider to the Converter in Compound Engineering Plugin

> Learn how to add a new target provider to the converter in the EveryInc compound engineering plugin. Define bundle types, implement converter and writer functions, and register your provider.

- Repository: [Every/compound-engineering-plugin](https://github.com/everyinc/compound-engineering-plugin)
- Tags: how-to-guide
- Published: 2026-02-16

---

**To add a new target provider to the converter, define a TypeScript bundle type, implement a converter function, create a writer function, and register the provider in the central targets map.**

The **EveryInc/compound-engineering-plugin** is an open-source tool that converts Claude Code plugins into formats compatible with various AI coding platforms. When you need to support a new AI platform, you must add a new target provider to the converter. This process involves creating four interconnected components that transform the internal plugin representation into the target platform's specific bundle format.

## Architecture Overview

The converter uses a layered architecture to isolate platform-specific logic. When you add a new target provider to the converter, you implement four distinct layers:

- **Bundle Definition**: A TypeScript interface describing the output structure expected by the provider
- **Converter**: A function that transforms `ClaudePlugin` into the target bundle format
- **Writer**: A function that persists the bundle to disk according to the target's conventions
- **Registry**: A central map in [`src/targets/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/index.ts) that wires the provider into the CLI

## Step-by-Step Implementation

### Step 1: Define the Bundle Type

Create a new file at `src/types/<provider>.ts` that exports the bundle interface. This type describes every field the target platform requires.

```typescript
// src/types/mytool.ts
export type MyToolBundle = {
  config: Record<string, unknown>
  prompts: { name: string; content: string }[]
  assets?: { path: string; data: Buffer }[]
}

```

### Step 2: Implement the Converter

Add a converter at `src/converters/claude-to-<provider>.ts`. This function walks the `ClaudePlugin` tree and maps Claude-specific concepts to the target provider's format.

```typescript
// src/converters/claude-to-mytool.ts
import { formatFrontmatter } from "../utils/frontmatter"
import type { ClaudePlugin } from "../types/claude"
import type { MyToolBundle } from "../types/mytool"
import type { ClaudeToOpenCodeOptions } from "./claude-to-opencode"

export function convertClaudeToMyTool(
  plugin: ClaudePlugin,
  _options: ClaudeToOpenCodeOptions,
): MyToolBundle {
  const prompts = plugin.commands.map((c) => ({
    name: c.name,
    content: formatFrontmatter({ description: c.description }, c.body),
  }))
  
  return { 
    config: plugin.settings ?? {}, 
    prompts 
  }
}

```

### Step 3: Create the Writer

Implement the writer at `src/targets/<provider>.ts`. This function receives the bundle and writes it to the filesystem according to the target platform's conventions.

```typescript
// src/targets/mytool.ts
import path from "path"
import { ensureDir, writeText } from "../utils/files"
import type { MyToolBundle } from "../types/mytool"

export async function writeMyToolBundle(
  outputRoot: string,
  bundle: MyToolBundle,
): Promise<void> {
  const root = path.join(outputRoot, ".mytool")
  await ensureDir(root)
  
  await writeText(
    path.join(root, "config.json"), 
    JSON.stringify(bundle.config, null, 2)
  )
  
  const promptsDir = path.join(root, "prompts")
  await ensureDir(promptsDir)
  
  for (const p of bundle.prompts) {
    await writeText(
      path.join(promptsDir, `${p.name}.md`), 
      p.content + "\n"
    )
  }
}

```

### Step 4: Register the Provider

Edit [`src/targets/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/index.ts) to wire the new provider into the CLI. Add an entry to the `targets` map that references your converter and writer.

```typescript
// src/targets/index.ts (excerpt)
import { convertClaudeToMyTool } from "../converters/claude-to-mytool"
import { writeMyToolBundle } from "./mytool"
import type { MyToolBundle } from "../types/mytool"

export const targets = {
  // ... existing providers ...
  
  mytool: {
    name: "mytool",
    implemented: true,
    convert: convertClaudeToMyTool as TargetHandler<MyToolBundle>["convert"],
    write: writeMyToolBundle as TargetHandler<MyToolBundle>["write"],
  },
}

```

The `implemented` flag tells the CLI that the provider is ready for use. The generic cast mirrors the existing entries for `codex`, `opencode`, and other platforms.

## Testing Your New Provider

After you add a new target provider to the converter, you must verify it with unit and integration tests. Create test files following the existing patterns:

- `tests/<provider>-converter.test.ts` – Validates that `convertClaudeTo<Provider>` produces valid bundles
- `tests/<provider>-writer.test.ts` – Confirms that `write<Provider>Bundle` creates the correct directory structure and files
- [`tests/cli.test.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/tests/cli.test.ts) – Add an integration test case that runs `install --to <provider>` against a fixture plugin

Run the full test suite with `bun test` to ensure your provider does not break existing functionality.

## Summary

To add a new target provider to the converter in the Compound Engineering Plugin, implement these four components:

- **Bundle Type**: Define the output structure in `src/types/<provider>.ts`
- **Converter**: Transform Claude plugins to the target format in `src/converters/claude-to-<provider>.ts`
- **Writer**: Persist bundles to disk in `src/targets/<provider>.ts`
- **Registry**: Register the provider in [`src/targets/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/index.ts) to enable CLI access

Once registered, users can convert plugins using `bunx @every-env/compound-plugin install <plugin> --to <provider>`.

## Frequently Asked Questions

### What is the minimum code required to add a new target provider to the converter?

You need four files: a type definition in `src/types/<provider>.ts`, a converter function in `src/converters/claude-to-<provider>.ts`, a writer function in `src/targets/<provider>.ts`, and a registry entry in [`src/targets/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/index.ts). The CLI wiring in [`src/commands/convert.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/convert.ts) requires no changes because it dynamically looks up providers in the registry.

### How do I handle platform-specific file layouts when I add a new target provider to the converter?

Implement the writer function in `src/targets/<provider>.ts` to create the specific directory structure required by the target platform. Use the helper functions from [`src/utils/files.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/utils/files.ts) such as `ensureDir` and `writeText` to create directories and write files. Map the bundle fields to the appropriate file paths and formats expected by the target AI coding platform.

### Do I need to modify the CLI command files to support a new target provider?

No. The [`src/commands/convert.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/convert.ts) file already reads the `--to` flag and looks up the provider in the `targets` registry defined in [`src/targets/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/index.ts). As long as you register your new provider in that registry with the `convert` and `write` functions, the CLI will automatically route commands to your implementation without additional wiring.

### What testing is required when adding a new target provider to the converter?

You should create unit tests for both the converter and writer functions, following the patterns in [`tests/codex-converter.test.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/tests/codex-converter.test.ts) and [`tests/codex-writer.test.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/tests/codex-writer.test.ts). Additionally, add an integration test in [`tests/cli.test.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/tests/cli.test.ts) that verifies the end-to-end flow using `install --to <provider>`. Run `bun test` to ensure your provider passes and does not regress existing functionality.