# How the Compound CLI Resolves Plugin Paths from GitHub Repositories

> Discover how the Compound CLI resolves plugin paths from GitHub repositories. Learn about the three stage pipeline: local checks, GitHub cloning, and plugin validation.

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

---

**The Compound CLI resolves plugin paths through a three-stage pipeline that first checks for local filesystem paths, then clones the repository from GitHub into a temporary directory, and finally validates the requested plugin exists within the `plugins/` subdirectory.**

When you execute `compound-plugin install my-plugin`, the CLI must translate a simple string identifier into a concrete filesystem location containing the Claude plugin source code. This resolution logic lives in the `EveryInc/compound-engineering-plugin` repository and handles both local development workflows and remote GitHub installations through a deterministic fallback strategy.

## The Three-Stage Resolution Process

The entry point `resolvePluginPath()` in [`src/commands/install.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/install.ts) orchestrates the entire resolution flow through three distinct stages.

### Stage 1: Distinguishing Local vs. Remote Paths

First, the CLI determines whether your input refers to a local directory or a remote GitHub repository. The `resolvePluginPath()` function checks if the argument starts with `.`, `/`, or `~` (lines 41-49).

If detected as a local path, the CLI expands the tilde notation using `expandHome()` from [`src/utils/resolve-home.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/utils/resolve-home.ts), then validates existence via `pathExists()` from [`src/utils/files.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/utils/files.ts). Valid local paths return immediately without any network operations.

### Stage 2: Fetching from GitHub

When the input is not a local path, the CLI invokes `resolveGitHubPluginPath()` (lines 93-115). This function creates a temporary directory and determines the source URL through `resolveGitHubSource()`.

By default, the CLI clones from the main `compound-engineering-plugin` repository. However, you can override this via the `COMPOUND_PLUGIN_GITHUB_SOURCE` environment variable to use forks or private mirrors.

The `cloneGitHubRepo()` helper (lines 23-33) executes a shallow clone using `git clone --depth 1` via Bun's `spawn` API. This minimizes bandwidth and storage by fetching only the latest commit.

### Stage 3: Locating the Plugin Directory

After cloning, the CLI validates the repository structure. It expects plugins to reside under `plugins/<plugin-name>` within the cloned repository (lines 123-139).

If the directory exists, `resolveGitHubPluginPath()` returns an object containing:
- `path`: The absolute path to the plugin directory
- `cleanup`: An async function that removes the temporary clone directory

If the plugin directory is missing, the cleanup function executes immediately to delete the temporary files, and the CLI throws an error indicating the plugin was not found in the repository.

## Key Helper Functions and Utilities

Several utility modules support the resolution pipeline:

| Function | Location | Purpose |
|----------|----------|---------|
| `expandHome` / `resolveTargetHome` | [`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 for local path resolution |
| `pathExists` | [`src/utils/files.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/utils/files.ts) | Async wrapper around `fs.access` to safely verify filesystem existence |
| `cloneGitHubRepo` | [`src/commands/install.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/commands/install.ts) (lines 23-33) | Executes shallow git clones via Bun's spawn API |

## Practical Usage Examples

Install a plugin from the default GitHub repository:

```bash
compound-plugin install my-awesome-skill

```

Install a local plugin during development:

```bash
compound-plugin install ./my-local-plugin
compound-plugin install ~/projects/my-plugin

```

Use a forked or private repository:

```bash
COMPOUND_PLUGIN_GITHUB_SOURCE=https://github.com/YourOrg/compound-engineering-plugin \
  compound-plugin install my-awesome-skill

```

Programmatic usage of the resolution logic:

```typescript
import { resolvePluginPath } from "./src/commands/install"

// Resolves "my-plugin" to a temporary GitHub clone
const result = await resolvePluginPath("my-plugin")

console.log(result.path)      // /tmp/compound-plugin-abc123/plugins/my-plugin
await result.cleanup?.()     // Removes the temporary directory

```

## Summary

- The CLI distinguishes local paths (starting with `.`, `/`, or `~`) from remote GitHub identifiers before attempting any network operations.
- Remote resolution clones the `compound-engineering-plugin` repository into a temporary directory using a shallow git clone for performance.
- The CLI expects plugins to follow the `plugins/<plugin-name>` directory structure within the repository and returns a cleanup function to remove temporary files after installation.
- Override the default GitHub source using the `COMPOUND_PLUGIN_GITHUB_SOURCE` environment variable for forks or private mirrors.

## Frequently Asked Questions

### How does the CLI handle local plugin paths versus GitHub repositories?

The CLI checks if the provided argument starts with `.`, `/`, or `~` to identify local filesystem paths. If detected, it expands the path using `expandHome()` and verifies existence with `pathExists()`. If the argument does not match local path patterns, the CLI treats it as a GitHub repository identifier and proceeds to clone the default or configured repository source.

### Can I install plugins from a forked version of the repository?

Yes. Set the `COMPOUND_PLUGIN_GITHUB_SOURCE` environment variable to your fork's URL before running the install command. The `resolveGitHubSource()` function checks this environment variable first, allowing you to override the default `EveryInc/compound-engineering-plugin` repository with private mirrors or organizational forks.

### What happens if the requested plugin does not exist in the repository?

If the CLI cannot find a directory matching `plugins/<plugin-name>` within the cloned repository, it immediately executes the cleanup function to delete the temporary clone directory and throws an error. This ensures no orphaned temporary files remain on your filesystem when requesting non-existent plugins.