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

> Understand how the sync command creates symlinks for zero-copy skill deployment with live updates when using the Compound Engineering Plugin. Learn how it works with symlinked skills.

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

---

**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)](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)](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 forceSymlink Utility

The core symlink creation logic resides in `forceSymlink`, implemented in [`src/utils/symlink.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/utils/symlink.ts). This utility safely creates or replaces symbolic links while protecting existing data:

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

## Benefits of Using Symlinks for Skill Sync

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:

- **Droid** ([`src/sync/droid.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/sync/droid.ts)): Creates symlinks under `~/.factory/skills/` and generates Droid-specific metadata.
- **Cursor** ([`src/sync/cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/sync/cursor.ts)): Populates `~/.cursor/skills/` with symlinks and writes an [`mcp.json`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/mcp.json) configuration file.
- **Pi** ([`src/sync/pi.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/sync/pi.ts)): Establishes symlinks and creates [`mcporter.json`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/mcporter.json) for the Pi platform.

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`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/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`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/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

### What happens if a real directory already exists where the sync command wants to create a symlink?

The `forceSymlink` utility in [`src/utils/symlink.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/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`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/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.