How Claude Command Namespacing Converts to Directory Structures in the Compound Engineering Plugin

Claude command namespacing converts to directory structures by splitting colon-separated command names into path segments, normalizing each segment for filesystem safety, and joining them with forward slashes so that Node.js path utilities automatically create nested subdirectories during the Gemini bundle conversion process.

The EveryInc/compound-engineering-plugin bridges Claude Desktop plugins with Gemini bundles, handling the transformation of Claude's colon-based command namespacing into hierarchical directory structures. Understanding how Claude command namespacing maps to filesystem paths is essential for debugging conversion issues and organizing large command sets logically.

Understanding Claude Command Namespacing

Claude Desktop plugins support namespaced commands using colon notation (e.g., workflows:plan). This convention allows developers to group related commands under logical categories, preventing name collisions and improving discoverability. When the compound-engineering-plugin converts these commands for Gemini compatibility, it preserves this hierarchy by translating colons into directory separators.

The Conversion Pipeline: From Colons to Directories

The transformation from Claude command namespacing to directory structures occurs in three distinct phases within the converter logic.

Step 1: Parsing Namespace Segments

The process begins in src/converters/claude-to-gemini.ts where the resolveCommandPath function splits the command name on colons and normalizes each segment:

function resolveCommandPath(name: string): string[] {
  return name.split(":").map((segment) => normalizeName(segment))
}

This function takes a name like workflows:plan and returns an array ["workflows", "plan"] after applying filesystem-safe normalization to each segment【link src/converters/claude-to-gemini.ts#L62-L66】.

Step 2: Building the Filesystem Path

The converter then joins these segments with forward slashes to create a path key:

const commandPath = resolveCommandPath(command.name)
const pathKey = commandPath.join("/")
uniqueName(pathKey, usedNames) // tracks deduplication

The pathKey variable now contains the slash-separated path (e.g., "workflows/plan"), which serves as the unique identifier for the command file【link src/converters/claude-to-gemini.ts#L62-L66】.

Step 3: Writing to Nested Directories

Finally, the src/targets/gemini.ts writer uses Node.js path utilities to create the nested structure:

await writeText(path.join(paths.commandsDir, `${command.name}.toml`), command.content + "\n")

Because command.name contains the forward slashes from the previous step (e.g., "workflows/plan"), path.join automatically creates the workflows subdirectory before writing plan.toml【link src/targets/gemini.ts#L21-L25】.

Code Example: Converting a Namespaced Command

Consider a Claude plugin command defined as:

{
  "name": "workflows:plan",
  "description": "Create a plan for the workflow",
  "body": "Generate a comprehensive plan..."
}

After conversion by the compound-engineering-plugin, this becomes the following filesystem structure:


.gemini/
 └─ commands/
     └─ workflows/
         └─ plan.toml

The TOML file contains:

description = "Create a plan for the workflow"
prompt = """Generate a comprehensive plan..."""

Why Directory-Based Namespacing Matters

This conversion strategy provides three critical benefits for Gemini bundle compatibility:

  • Logical grouping – Namespaces become physical folders, making large command sets navigable in file explorers and version control systems.
  • Compatibility with Gemini CLI – The Gemini CLI expects commands under commands/ with optional sub-folders that map to command groups, matching the converted structure exactly.
  • Deterministic deduplication – The uniqueName helper tracks the full path key (e.g., "workflows/plan"), ensuring that two commands with identical names in different namespaces cannot clash during conversion.

Summary

  • Claude command namespacing uses colons (:) to separate logical segments (e.g., category:command).
  • The converter in src/converters/claude-to-gemini.ts splits these names on colons and normalizes each segment via resolveCommandPath.
  • Segments are joined with forward slashes to create a filesystem path like category/command.
  • The writer in src/targets/gemini.ts uses path.join with these slash-separated names, causing Node.js to automatically create nested subdirectories.
  • The resulting directory structure mirrors the original namespace hierarchy, ensuring Gemini CLI compatibility and logical command organization.

Frequently Asked Questions

What delimiter does Claude use for command namespacing?

Claude Desktop plugins use the colon (:) as the namespace delimiter. For example, a command named workflows:plan indicates that "workflows" is the namespace and "plan" is the specific command within that group.

How does the plugin prevent naming conflicts between namespaced commands?

The plugin uses a uniqueName helper function that tracks the full path key (e.g., "workflows/plan") rather than just the final command name. This ensures that two commands like workflows:plan and templates:plan are treated as distinct entries because their full path keys differ, preventing filesystem collisions during the conversion process.

Can namespaces be nested deeper than one level?

Yes, the conversion logic supports arbitrary nesting depths. A command named team:workflows:plan would be split into three segments (["team", "workflows", "plan"]), resulting in a directory structure of .gemini/commands/team/workflows/plan.toml. The resolveCommandPath function handles any number of colon-separated segments.

What file extension is used for converted command files?

The plugin writes converted commands as TOML files (.toml extension). During the write phase in src/targets/gemini.ts, the code explicitly appends .toml to the command name (e.g., ${command.name}.toml), resulting in files like plan.toml within their respective namespace directories.

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 →