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

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 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.

// 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.

// 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.

// 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 to wire the new provider into the CLI. Add an entry to the targets map that references your converter and writer.

// 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 – 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 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. The CLI wiring in 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 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 file already reads the --to flag and looks up the provider in the targets registry defined in 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 and tests/codex-writer.test.ts. Additionally, add an integration test in 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →