How TypeScript Types Define the Conversion Bundle Structure in the Compound‑Engineering Plugin

The conversion bundle structure is strictly enforced by the OpenCodeBundle type in src/types/opencode.ts, which defines the exact shape of the configuration, agent files, plugin files, and skill directories that the CLI generates.

The compound-engineering-plugin relies on rigorous TypeScript type definitions to guarantee that every conversion from Claude plugins to OpenCode projects produces a valid, type-safe bundle. These types, centralized in src/types/opencode.ts, serve as the single source of truth for the entire conversion pipeline.

The Core Type Definition: OpenCodeBundle

At the heart of the system lies the OpenCodeBundle type, exported from src/types/opencode.ts (lines 49‑54). This type mandates four required properties that collectively describe every artifact the conversion process must produce.

export type OpenCodeBundle = {
  config: OpenCodeConfig
  agents: OpenCodeAgentFile[]
  plugins: OpenCodePluginFile[]
  skillDirs: { sourceDir: string; name: string }[]
}
  • config – A full‑featured OpenCodeConfig object that mirrors the schema used by OpenCode agents.
  • agents – An array of OpenCodeAgentFile objects, each containing a name and raw content, representing generated agent source files.
  • plugins – Analogous to agents, but for OpenCodePluginFile objects that capture plugin source files.
  • skillDirs – A list of directories containing reusable skills; each entry records the original sourceDir and the name under which the skill appears in the output tree.

Nested Type Definitions That Shape the Bundle

The OpenCodeBundle type references several nested structures that enforce granular constraints on the conversion output.

OpenCodeConfig – The Project Configuration

Located in the same file (lines 3‑12), the OpenCodeConfig type defines the JSON structure written to opencode.json. It includes optional schema URL, default model, tool toggles, permission maps, agent‑specific overrides, command templates, and MCP server definitions.

OpenCodeAgentFile and OpenCodePluginFile

These types (lines 39‑47) are simple but critical structures:

export type OpenCodeAgentFile = {
  name: string
  content: string
}

export type OpenCodePluginFile = {
  name: string
  content: string
}

They capture the rendered source text for agents and plugins respectively, ensuring that every file produced by the converter has a filename and valid TypeScript content.

Supporting Configuration Types

Additional types like OpenCodeAgentConfig, OpenCodeCommandConfig, and OpenCodeMcpServer define sub‑objects referenced within OpenCodeConfig, allowing granular control over agent behavior, CLI commands, and MCP server integrations.

How the Types Drive the Conversion Pipeline

The type definitions are not merely documentation; they enforce contracts across the codebase. In src/converters/claude-to-opencode.ts, the convertClaudeToOpencode function returns an OpenCodeBundle, guaranteeing that every conversion produces a structurally valid output.

The writer modules in src/targets/opencode.ts consume these typed bundles to serialize opencode.json, write agent files to disk, create plugin directories, and copy skill directories. Because the types are strict, the CLI can guarantee that generated OpenCode projects are well‑formed and type‑safe.

Practical Example: Constructing a Valid Bundle

You can manually instantiate an OpenCodeBundle for testing or custom scripts:

import {
  OpenCodeBundle,
  OpenCodeConfig,
  OpenCodeAgentFile,
  OpenCodePluginFile,
} from './src/types/opencode'

// Minimal configuration
const config: OpenCodeConfig = {
  model: 'gpt-4o-mini',
  tools: { websearch: true },
}

// Example agent file
const agent: OpenCodeAgentFile = {
  name: 'myAgent.ts',
  content: `
    import { Agent } from 'opencode'
    export const myAgent = new Agent({ model: 'gpt-4o-mini' })
  `,
}

// Example plugin file
const plugin: OpenCodePluginFile = {
  name: 'myPlugin.ts',
  content: `
    export const greet = (name: string) => \`Hello, \${name}!\`
  `,
}

// Assemble the bundle
const bundle: OpenCodeBundle = {
  config,
  agents: [agent],
  plugins: [plugin],
  skillDirs: [{ sourceDir: 'src/skills', name: 'mySkill' }],
}

// The bundle can now be passed to the writer
// writer.writeOpenCodeBundle(bundle, outputPath)

Summary

  • The OpenCodeBundle type in src/types/opencode.ts strictly defines the conversion bundle structure through four required properties: config, agents, plugins, and skillDirs.
  • Nested types like OpenCodeConfig, OpenCodeAgentFile, and OpenCodePluginFile enforce the shape of configuration files and source artifacts.
  • These TypeScript types act as compile-time contracts for converters in src/converters/claude-to-opencode.ts and writers in src/targets/opencode.ts, ensuring every generated OpenCode project is type-safe and structurally valid.

Frequently Asked Questions

What is the OpenCodeBundle type used for?

The OpenCodeBundle type serves as the central schema for the compound-engineering-plugin's output. It ensures that every conversion from Claude plugins to OpenCode projects produces a consistent, type-safe structure containing the configuration, agents, plugins, and skill directories required by the OpenCode CLI.

Where are the conversion bundle types defined?

All TypeScript types that define the conversion bundle structure are located in src/types/opencode.ts within the EveryInc/compound-engineering-plugin repository. This file exports OpenCodeBundle, OpenCodeConfig, OpenCodeAgentFile, OpenCodePluginFile, and related configuration sub-types.

How do the types ensure type safety during conversion?

The types enforce compile-time contracts across the conversion pipeline. The convertClaudeToOpencode function in src/converters/claude-to-opencode.ts returns a strictly typed OpenCodeBundle, while the writer modules in src/targets/opencode.ts consume these typed structures to serialize output. This prevents malformed configurations or missing files from reaching the disk.

Can I manually create an OpenCodeBundle for testing?

Yes, you can manually instantiate an OpenCodeBundle by importing the types from src/types/opencode.ts and constructing the required properties: an OpenCodeConfig object, arrays of OpenCodeAgentFile and OpenCodePluginFile objects, and skill directory mappings. This approach is useful for unit testing converters or generating synthetic OpenCode projects programmatically.

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 →