# How to Run the Converter CLI Locally for Plugin Development

> Learn how to run the converter CLI locally for plugin development. Install Bun and execute the command from the repository root to streamline your workflow.

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

---

**To run the converter CLI locally, install Bun, execute `bun run src/index.ts convert <plugin-path> --to <target>` from the repository root, and specify your output directory with `--output`.**

The EveryInc/compound-engineering-plugin repository provides a Bun/TypeScript CLI that transforms Claude Code plugins into multiple AI agent formats. When you run the converter CLI locally for plugin development, you can iterate rapidly on plugin manifests and test conversions against OpenCode, Codex, Droid, Cursor, Pi, and Gemini targets without publishing.

## CLI Architecture and Entry Point

The CLI bootstrap lives in [`src/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/index.ts) and uses the **citty** framework to define sub-commands. The entry point registers four commands: `convert`, `install`, `list`, and `sync`.

```typescript
#!/usr/bin/env bun
import { defineCommand, runMain } from "citty"
import convert from "./commands/convert"
import install from "./commands/install"
import listCommand from "./commands/list"
import sync from "./commands/sync"

const main = defineCommand({
  meta: { name: "compound-plugin", version: "0.1.0" },
  subCommands: {
    convert: () => convert,
    install: () => install,
    list:   () => listCommand,
    sync:   () => sync,
  },
})

runMain(main)

```

The parser forwards control to [`src/commands/convert.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/convert.ts) when you invoke the `convert` sub-command.

## The Convert Command Implementation

The conversion logic resides in [`src/commands/convert.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/convert.ts). This module orchestrates argument parsing, plugin loading, path resolution, target dispatch, and file writing.

### Argument Parsing and Validation

The command declares arguments using citty's `args` block. Key parameters include:

- `source` – Path to the Claude plugin directory.
- `to` – Primary target format (`opencode`, `codex`, `droid`, `cursor`, `pi`, `gemini`).
- `output` – Explicit output directory (defaults to target-specific paths).
- `codexHome` – Custom root for Codex output (overrides `~/.codex`).
- `piHome` – Custom root for Pi output (overrides `~/.pi/agent`).
- `also` – Comma-separated list of additional targets to generate.
- `permissions`, `agentMode`, `inferTemperature` – Target-specific tuning flags.

### Plugin Loading and Resolution

The command loads the source plugin using `loadClaudePlugin` from [`src/parsers/claude.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/parsers/claude.ts). It then resolves output paths through three utilities:

1. **`resolveOutputRoot`** – Defaults to `~/.config/opencode` when no `--output` is supplied.
2. **`resolveTargetHome`** – Expands `--codex-home` or `--pi-home` paths.
3. **`resolveTargetOutputRoot`** – Determines the final directory based on the primary target.

### Target Conversion and Writing

Conversion delegates to the appropriate handler from [`src/targets/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/index.ts), which exports `convertClaudeToOpenCode`, `convertClaudeToCodex`, and similar functions. The workflow follows this pipeline:

1. **Parse** the Claude plugin manifest ([`plugin.json`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/plugin.json)) and collect agents, commands, skills, hooks, and MCP servers.
2. **Transform** each element using a dedicated converter (e.g., [`src/converters/claude-to-opencode.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-opencode.ts)).
3. **Assemble** a `Bundle` object containing files (`plugins`, `agents`, `skills`) and generated configuration.
4. **Write** the bundle via `target.write(primaryOutputRoot, bundle)` and print a success message.

### Multi-Target and Post-Processing

The `--also` flag triggers additional conversions in a single invocation. The CLI parses the comma-separated list, runs each extra conversion, and writes to its respective root (e.g., writing Codex output to `codexHome` when OpenCode is primary).

If the final target set includes Codex, the CLI ensures the generated [`AGENTS.md`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/AGENTS.md) file exists via `ensureCodexAgentsFile` from [`src/utils/codex-agents.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/utils/codex-agents.ts).

## Local Development Setup

Before running the converter CLI locally for plugin development, ensure you have **Bun** installed. The CLI is built specifically for the Bun runtime.

1. **Install Bun** – Follow the instructions at [bun.sh](https://bun.sh).

2. **Clone the repository**

   ```bash
   git clone https://github.com/EveryInc/compound-engineering-plugin.git
   cd compound-engineering-plugin
   ```

3. **Install dependencies**

   ```bash
   bun install
   ```

## Running the Converter CLI Locally

Once dependencies are installed, you can invoke the CLI using `bun run src/index.ts` followed by the `convert` sub-command and appropriate flags.

### Basic Conversion to OpenCode

Convert a local plugin directory to the OpenCode format and write it to a specific output folder:

```bash
bun run src/index.ts convert ./plugins/compound-engineering \
  --to opencode \
  --output ./tmp/opencode-output

```

* `./plugins/compound-engineering` – Path to the Claude plugin you are iterating on.
* `--to opencode` – Specifies the target format.
* `--output ./tmp/opencode-output` – Explicit directory for the generated bundle; omitted defaults to `~/.config/opencode`.

### Converting to Codex with Custom Home Directory

When targeting Codex, you can override the default `~/.codex` location:

```bash
bun run src/index.ts convert ./plugins/compound-engineering \
  --to codex \
  --codex-home ~/.my-codex-root

```

The `--codex-home` flag expands `~` via `resolveTargetHome` and directs output to your custom root.

### Generating Multiple Formats Simultaneously

Use the `--also` flag to generate additional targets in a single invocation:

```bash
bun run src/index.ts convert ./plugins/compound-engineering \
  --to opencode \
  --also codex,pi \
  --codex-home ~/.my-codex \
  --pi-home ~/.my-pi \
  --output ./tmp/multi-output

```

The primary target (`opencode`) respects `--output`, while extra targets write to their respective homes (`--codex-home`, `--pi-home`).

### Using Custom Pi Home

For Pi-specific development, override the default `~/.pi/agent` path:

```bash
bun run src/index.ts convert ./plugins/compound-engineering \
  --to pi \
  --pi-home ./my-pi-root

```

## Development Workflow Tips

| Goal | Recommended Practice |
|---|---|
| **Rapid iteration** | Point `--output` to a temporary directory (e.g., `mktemp -d`) and re-run the command after each manifest change. |
| **Inspect generated files** | The CLI writes files exactly as consumed by target tools; verify front-matter, prompt content, and directory layout in the output folder. |
| **Test against the built-in suite** | Run `bun test` to ensure converter changes haven't broken existing target implementations. |
| **Add a new target** | Follow the checklist in [`AGENTS.md`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/AGENTS.md) under *Adding a New Target Provider*; implement `convertClaudeTo…` and a matching writer, then register in [`src/targets/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/index.ts). |
| **Debugging** | Insert `console.log` statements in the relevant converter (e.g., [`src/converters/claude-to-pi.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-pi.ts)) and re-run; output appears in the terminal immediately. |

## Key Source Files Reference

| File | Role |
|---|---|
| [`src/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/index.ts) | CLI bootstrap using citty; registers `convert`, `install`, `list`, and `sync` sub-commands. |
| [`src/commands/convert.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/convert.ts) | Implements the `convert` sub-command, orchestrating argument parsing, plugin loading, path resolution, and target dispatch. |
| [`src/utils/resolve-home.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/utils/resolve-home.ts) | Expands `~` to the user's home directory and resolves target-specific home paths. |
| [`src/targets/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/index.ts) | Registry of all target providers (`opencode`, `codex`, `droid`, `cursor`, `pi`, `gemini`) and their `convert`/`write` functions. |
| [`src/converters/claude-to-opencode.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-opencode.ts) | Core OpenCode conversion logic transforming agents to Markdown and commands to JSON. |
| [`src/converters/claude-to-codex.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-codex.ts) | Codex-specific conversion generating prompts and skills. |
| [`src/converters/claude-to-pi.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-pi.ts) | Pi conversion handling prompts, extensions, and MCPorter configuration. |
| [`src/parsers/claude.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/parsers/claude.ts) | Reads a Claude plugin directory into a typed `ClaudePlugin` object. |
| [`src/utils/codex-agents.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/utils/codex-agents.ts) | Guarantees the [`AGENTS.md`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/AGENTS.md) file exists for Codex output bundles. |

## Summary

- The **compound-engineering-plugin** CLI is a Bun-based tool defined in [`src/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/index.ts) that uses the **citty** framework to route commands.
- The **`convert`** sub-command in [`src/commands/convert.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/convert.ts) handles the full pipeline: parsing arguments, loading the plugin via `loadClaudePlugin`, resolving output paths, and dispatching to target converters.
- You can run the converter CLI locally for plugin development using `bun run src/index.ts convert <path> --to <target>`, with optional flags like `--output`, `--codex-home`, `--pi-home`, and `--also` for multi-target generation.
- Key utilities like [`resolve-home.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/resolve-home.ts) and [`codex-agents.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/codex-agents.ts) manage path expansion and post-conversion file guarantees, while [`src/targets/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/index.ts) registers all available conversion targets.

## Frequently Asked Questions

### What is the primary entry point for the CLI?

The primary entry point is [`src/index.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/index.ts). This file defines the main command using the **citty** library, registers sub-commands including `convert`, `install`, `list`, and `sync`, and invokes `runMain(main)` to start execution. When you run `bun run src/index.ts`, you are invoking this bootstrap module.

### How do I convert a plugin to multiple targets at once?

Use the `--also` flag followed by a comma-separated list of additional targets. For example, `--also codex,pi` generates Codex and Pi outputs alongside your primary target. Each extra target writes to its own home directory (respecting `--codex-home` or `--pi-home` if provided), while the primary target uses the path specified by `--output`.

### Where does the CLI write files by default?

Default output locations depend on the target format. When `--output` is omitted, the CLI uses `~/.config/opencode` for OpenCode, `~/.codex` for Codex, and `~/.pi/agent` for Pi. The `resolveOutputRoot` and `resolveTargetHome` functions in [`src/utils/resolve-home.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/utils/resolve-home.ts) handle these defaults and expand the `~` shorthand to your actual home directory.

### How can I debug conversion logic during development?

Insert `console.log` statements directly into the converter files (such as [`src/converters/claude-to-opencode.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-opencode.ts) or [`src/converters/claude-to-pi.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-pi.ts)) and re-run the CLI command. Output appears immediately in your terminal. For systematic verification, run `bun test` to execute the built-in test suite and ensure your changes haven't broken existing target implementations.