How the Sync Command Works with Symlinked Skills in the Compound Engineering Plugin

The sync command creates symbolic links between your Claude home configuration and target agent platforms, enabling zero-copy skill deployment with live updates.

The sync command in the EveryInc/compound-engineering-plugin efficiently propagates Claude skills to supported agent platforms like OpenCode, Codex, and Cursor. By leveraging symbolic links rather than file copies, the command maintains a single source of truth while enabling immediate updates across all synced platforms.

Sync Command Architecture and Entry Point

The CLI entry point resides in [src/commands/sync.ts](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/sync.ts). This module validates the target platform argument—accepting opencode, codex, pi, droid, or cursor—and loads the Claude home configuration via loadClaudeHome.

After resolving the destination root for the chosen platform (for example, ~/.factory for Droid), the command delegates to platform-specific sync functions such as syncToDroid or syncToCursor.

How Symlinked Skills Are Created

Each platform-specific sync module in src/sync/ follows an identical pattern for creating skill symlinks. The process iterates over config.skills, validates each skill name, and establishes symbolic links in the platform's skills directory.

Validating Skill Names and Security

Before creating any links, the system validates skill names using isValidSkillName from [src/utils/symlink.ts](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/utils/symlink.ts). This sanitization prevents path-traversal attacks by rejecting names containing .., /, or other dangerous characters that could escape the intended directory structure.

The core symlink creation logic resides in forceSymlink, implemented in src/utils/symlink.ts. This utility safely creates or replaces symbolic links while protecting existing data:

export async function forceSymlink(source: string, target: string): Promise<void> {
  try {
    const stat = await fs.lstat(target)
    if (stat.isSymbolicLink()) {
      await fs.unlink(target)                 // replace existing symlink
    } else if (stat.isDirectory()) {
      throw new Error(`Cannot create symlink at ${target}: a real directory exists there.`)
    } else {
      await fs.unlink(target)                 // replace regular file
    }
  } catch (err) {
    if ((err as NodeJS.ErrnoException).code !== "ENOENT") throw err
  }
  await fs.symlink(source, target)            // create new symlink
}

This implementation ensures that only existing symlinks are overwritten, while real directories trigger an error to prevent accidental data loss.

The symlink-based approach in the compound-engineering-plugin provides three critical advantages:

  • Zero-copy deployment – Skills exist as pointers to the original source directories, eliminating disk space duplication across multiple agent platforms.
  • Live updates – Modifications to a skill in the Claude home directory immediately propagate to all synced platforms without requiring re-sync operations.
  • Safety guarantees – The forceSymlink utility prevents the sync command from destroying real directories, ensuring that existing platform configurations remain intact.

Platform-Specific Implementations

While all platforms use the same symlink mechanism, each target module in src/sync/ handles platform-specific configuration files after establishing skill links:

In each case, the symlink creation precedes any additional configuration writes, ensuring that skill references are established before platform-specific metadata is generated.

Summary

  • The sync command in src/commands/sync.ts orchestrates the deployment of Claude skills to multiple agent platforms.
  • Symbolic links are created via forceSymlink in src/utils/symlink.ts, enabling zero-copy skill references.
  • Skill name validation prevents path-traversal attacks before symlink creation.
  • Platform-specific modules in src/sync/ handle unique configuration requirements while sharing the common symlink mechanism.
  • The symlink approach ensures live updates and safety guarantees across all supported platforms.

Frequently Asked Questions

The forceSymlink utility in src/utils/symlink.ts detects existing directories via fs.lstat and throws an error before making any changes. This prevents the sync command from accidentally overwriting real data, while existing symlinks are safely replaced.

Do I need to re-run the sync command after editing a skill?

No. Because the sync command creates symbolic links rather than file copies, any changes you make to the original skill directory in ~/.claude/ are immediately reflected in the synced platform directories. The symlink acts as a live pointer to the source.

Which agent platforms are currently supported by the sync command?

The sync command supports OpenCode, Codex, Pi, Droid, and Cursor. Each platform has a dedicated sync module in src/sync/ that handles platform-specific configuration while using the shared symlink mechanism for skill deployment.

How does the sync command prevent malicious skill names from compromising the system?

Before creating any symlinks, the command validates skill names using isValidSkillName from src/utils/symlink.ts. This function rejects names containing path traversal sequences like .. or /, ensuring that symlinks can only be created within the intended platform skills directory.

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 →