# The Mechanism Behind .cursor Rules for Agent Activation in Compound Engineering Plugin

> Discover the five-step mechanism behind .cursor rules for agent activation in EveryInc's compound engineering plugin. Learn how agents transform into Markdown rules for runtime invocation.

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

---

**The mechanism behind .cursor rules for agent activation converts Claude agents into Markdown-based Cursor rules through a five-step pipeline that parses agent definitions, transforms their content for Cursor compatibility, and writes them as `.mdc` files to the `/.cursor/rules/` directory for on-demand runtime invocation.**

The Compound Engineering Plugin bridges Claude's agent architecture with Cursor's rule-based system. Understanding the mechanism behind .cursor rules for agent activation reveals how AI assistants written for Claude's ecosystem become executable instructions within Cursor's editor environment.

## How .cursor Rules Transform Claude Agents into Cursor-Compatible Instructions

The conversion process treats Claude agents as source material that must be normalized for Cursor's runtime. Each agent undergoes structural transformation where its body content, command references, and file paths are rewritten to match Cursor's rule syntax while preserving the original logic.

## The Five-Step Agent Activation Flow

### Step 1: Parsing Claude Plugin Definitions

The pipeline begins in [`src/parsers/claude.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/parsers/claude.ts), where the system parses raw Claude plugin files into structured objects including `ClaudeAgent`, `ClaudeCommand`, and related entities. This parsing phase extracts agent names, descriptions, capabilities, and body content from the original `.claude` format.

### Step 2: Agent-to-Rule Conversion

In [`src/converters/claude-to-cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-cursor.ts), the `convertAgentToRule` function transforms each `ClaudeAgent` into a `CursorRule` object. This step generates a unique, normalized kebab-case name using `uniqueName` and `normalizeName` to prevent collisions. The function constructs frontmatter containing the description and `alwaysApply: false`, ensuring the rule requires explicit invocation.

### Step 3: Content Transformation for Cursor Syntax

The `transformContentForCursor` function rewrites agent body content to match Cursor's expectations:

- **Task calls**: Converts `Task agent-name(args)` syntax into `Use the <skill> skill to: args` format
- **Slash commands**: Flattens nested command namespaces for Cursor compatibility
- **Path rewriting**: Updates `~/.claude/` and `.claude/` references to `~/.cursor/` and `.cursor/`
- **Agent references**: Transforms `@agent-name` mentions into "the `<rule-name>` rule" syntax

### Step 4: Rule File Generation

The `writeCursorBundle` function in [`src/targets/cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/cursor.ts) persists the transformed rules to disk. It combines formatted frontmatter with the transformed body using `formatFrontmatter`, then writes each rule as `<name>.mdc` to the `/.cursor/rules/` directory. This file-based contract enables Cursor's runtime to discover available rules.

### Step 5: Runtime Activation and Execution

When a user types `@<agent-name>` or references "the `<rule-name>` rule" in a Cursor session, the editor resolves this reference against the files in `/.cursor/rules/`. Because the generated rules specify `alwaysApply: false`, Cursor loads the rule on demand rather than automatically. The rule's Markdown content, including any "## Capabilities" section added during conversion, executes as instructions guiding the AI's behavior.

## Code Implementation: From Agent to Rule

### Converting Agents with convertAgentToRule

The core conversion logic resides in [`src/converters/claude-to-cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-cursor.ts):

```typescript
function convertAgentToRule(agent: ClaudeAgent, usedNames: Set<string>): CursorRule {
  const name = uniqueName(normalizeName(agent.name), usedNames)   // → unique, kebab‑case name
  const description = agent.description ?? `Converted from Claude agent ${agent.name}`

  const frontmatter = {
    description,
    alwaysApply: false,            // rule is not auto‑run
  }

  // body is transformed to Cursor‑compatible syntax
  let body = transformContentForCursor(agent.body.trim())
  if (agent.capabilities?.length) {
    const caps = agent.capabilities.map(c => `- ${c}`).join('\n')
    body = `## Capabilities\n${caps}\n\n${body}`.trim()

  }
  if (!body) body = `Instructions converted from the ${agent.name} agent.`

  const content = formatFrontmatter(frontmatter, body)          // ← front‑matter + body
  return { name, content }                                    // → CursorRule
}

```

### Transforming Content for Cursor Compatibility

The `transformContentForCursor` function handles syntax normalization:

```typescript
export function transformContentForCursor(body: string): string {
  // 1️⃣ Task agent calls → “Use the <skill> skill to: …”
  const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9-]*)\(([^)]+)\)/gm
  body = body.replace(taskPattern, (_, p, a, args) =>
    `${p}Use the ${normalizeName(a)} skill to: ${args.trim()}`)

  // 2️⃣ Slash command flattening
  const slashCmd = /(?<![:\w])\/([a-z][a-z0-9_:-]*?)(?=[\s,."')\]}`]|$)/gi
  body = body.replace(slashCmd, (m, c) => (c.includes('/') ? m : `/${flattenCommandName(c)}`))

  // 3️⃣ Path rewrite from .claude/ → .cursor/
  body = body.replace(/~\/\.claude\//g, "~/.cursor/").replace(/\.claude\//g, ".cursor/")

  // 4️⃣ @‑agent → “the <rule‑name> rule”
  const agentRef = /@([a-z][a-z0-9-]*-(?:agent|reviewer|researcher|analyst|specialist|oracle|sentinel|guardian|strategist))/gi
  body = body.replace(agentRef, (_, n) => `the ${normalizeName(n)} rule`)

  return body
}

```

### Example Output: A Generated .mdc Rule File

The conversion produces Markdown files with YAML frontmatter:

```markdown
---
description: Review security aspects of the code base.
alwaysApply: false
---

## Capabilities

- Detect vulnerable dependencies
- Enforce least‑privilege policies

When you notice a risky pattern, **the security-reviewer rule** will suggest mitigations.

```

When a user types `@security-reviewer` in Cursor, the runtime locates this file in `/.cursor/rules/` and executes the instructions.

## Key Source Files and Their Roles

The implementation spans several modules in the **Compound Engineering Plugin** repository:

- **[`src/parsers/claude.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/parsers/claude.ts)** – Parses Claude plugin definitions into structured `ClaudeAgent` objects.

- **[`src/converters/claude-to-cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-cursor.ts)** – Contains `convertAgentToRule` and `transformContentForCursor`, handling the core logic for agent-to-rule conversion and content normalization.

- **[`src/targets/cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/targets/cursor.ts)** – Implements `writeCursorBundle` to persist rules as `.mdc` files in the `/.cursor/rules/` directory.

- **[`src/types/cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/types/cursor.ts)** – Defines TypeScript interfaces including `CursorRule`, `CursorCommand`, and `CursorBundle`.

- **[`tests/cursor-converter.test.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/tests/cursor-converter.test.ts)** – Validates that Claude agents convert to correctly structured Cursor rules.

- **[`tests/cursor-writer.test.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/tests/cursor-writer.test.ts)** – Ensures `writeCursorBundle` creates the expected directory layout and file formats.

## Summary

- **Agent activation** relies on a file-based contract where Claude agents become Cursor rules stored in `/.cursor/rules/`.
- The **`convertAgentToRule`** function in [`src/converters/claude-to-cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-cursor.ts) generates unique, normalized rule names and sets `alwaysApply: false` to enable on-demand loading.
- **Content transformation** rewrites Task calls, slash commands, file paths, and agent references to match Cursor's expected syntax.
- Rules are persisted as **`.mdc` files** with YAML frontmatter, allowing the Cursor runtime to resolve `@<agent-name>` references and execute the embedded Markdown instructions.

## Frequently Asked Questions

### What triggers a .cursor rule to activate?

A rule activates when a user references it by typing `@<rule-name>` or mentioning "the `<rule-name>` rule" in a Cursor prompt. Because the Compound Engineering Plugin generates rules with `alwaysApply: false` in the frontmatter, they do not run automatically and require explicit invocation by the user.

### How does the conversion handle naming conflicts between agents?

The `convertAgentToRule` function in [`src/converters/claude-to-cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-cursor.ts) uses `uniqueName` and `normalizeName` utilities to generate kebab-case identifiers and checks them against a `usedNames` set. If a collision occurs, the function appends a suffix to ensure every rule file has a unique name, preventing filesystem and runtime conflicts.

### Can .cursor rules auto-apply without user invocation?

No. The conversion process explicitly sets `alwaysApply: false` in the rule frontmatter. This design ensures that agents converted from Claude's architecture behave as on-demand tools rather than persistent background processes, matching Cursor's rule-based execution model where users control when specific capabilities are invoked.

### What happens to Claude-specific syntax during conversion?

The `transformContentForCursor` function in [`src/converters/claude-to-cursor.ts`](https://github.com/EveryInc/compound-engineering-plugin/blob/main/src/converters/claude-to-cursor.ts) systematically rewrites Claude-specific constructs: Task invocations become skill-based instructions, slash commands are flattened to simple commands, file paths migrate from `.claude/` directories to `.cursor/`, and `@agent-name` references convert to "the `<rule-name>` rule" syntax. This ensures the resulting Markdown content is fully compatible with Cursor's rule engine.