From migration-tools
Migrate Claude Code configurations to Cursor equivalents using symlinks and markdown links to avoid content duplication
npx claudepluginhub cjuega/ai-plugins --plugin migration-toolsThis skill uses the workspace's default tool permissions.
Discover all Claude Code configuration files in this repository and create Cursor equivalents that reference the originals — no content duplication.
Migrates Agent projects to consistent Claude Code / Codex dual workspaces: audits rule files, identifies source-of-truth skills, unifies names, generates bridges. Use for messy or half-migrated setups.
Migrates configs from Cursor, Windsurf, Copilot, Continue, Aider, Cody, Codex to Claude Code. Discovers files, trims bloat, proposes and executes clean plans.
Converts Claude Code skills to OpenAI Codex, Google Gemini CLI, Antigravity, and Cursor. Generates platform-specific files like openai.yaml, AGENTS.md and compatibility reports.
Share bugs, ideas, or general feedback.
Discover all Claude Code configuration files in this repository and create Cursor equivalents that reference the originals — no content duplication.
| Source | Cursor equivalent | Strategy |
|---|---|---|
CLAUDE.md (symlink to AGENTS.md/.cursorrules) | — | Already compatible, nothing to do |
CLAUDE.md (plain, no @refs) | AGENTS.md | symlink to CLAUDE.md |
CLAUDE.md (@imports only) | AGENTS.md | hub file with markdown links per @import |
CLAUDE.md (inline + @imports) | AGENTS.md | inline content preserved + @imports replaced with markdown links |
.claude/agents/<name>.md (no @refs in body) | — | Cursor reads .claude/agents/ natively; no action needed |
.claude/agents/<name>.md (has @refs in body) | .cursor/agents/<name>.md | wrapper with adapted frontmatter + @refs → markdown links |
.claude/skills/<name>/SKILL.md | .cursor/skills/<name>/SKILL.md | transformed copy with adapted frontmatter + @refs → markdown links |
Run all discovery commands:
! readlink CLAUDE.md 2>/dev/null && echo "(CLAUDE.md is a symlink)" || echo "(CLAUDE.md is not a symlink)" ! ls CLAUDE.md 2>/dev/null || echo "(no CLAUDE.md)" ! ls .claude/agents/.md 2>/dev/null || echo "(no claude agents)" ! ls .claude/skills//SKILL.md 2>/dev/null || echo "(no claude skills)"
Then check for conflicts with existing Cursor configs:
! ls AGENTS.md 2>/dev/null || echo "(no existing AGENTS.md)" ! ls .cursor/agents/.md 2>/dev/null || echo "(no existing cursor agents)" ! ls .cursor/skills//SKILL.md 2>/dev/null || echo "(no existing cursor skills)"
For each discovered file:
CLAUDE.md strategy decision:
CLAUDE.md is a symlink to AGENTS.md or .cursorrules → Case A: already compatible, nothing to doCLAUDE.md is plain markdown with no @ references → Case B: symlink AGENTS.md → CLAUDE.mdCLAUDE.md contains only @path/to/file lines (possibly with surrounding text) → Case C: create AGENTS.md hub by replacing each @path/to/file with [filename](path/to/file)CLAUDE.md contains a mix of inline content and @ imports → Case D: preserve inline content, replace each @path/to/file with [filename](path/to/file)If AGENTS.md already exists (Cases B/C/D), flag it as a conflict and offer the user three options:
AGENTS.md unchanged and note it in the reportSubagent strategy decision (per agent):
@ import pointing to a path under .cursor/, skip it (already a wrapper around a Cursor original).@path/to/file patterns.@ references → no action: Cursor reads .claude/agents/ natively with lower priority than .cursor/agents/. Unknown Claude frontmatter fields are ignored by Cursor.@ references → create .cursor/agents/<name>.md wrapper (takes priority over .claude/agents/).Skill strategy decision (per skill):
migrate-cursor, migrate-to-cursor.@ import pointing to a path under .cursor/ or .agents/, skip it..cursor/skills/<name>/SKILL.md transformed copy.Subagent model mapping (Claude model: → Cursor model:):
sonnet → fastopus → slowhaiku → omit (note in report)Subagent field mapping:
background: true → omit (no Cursor equivalent; note in report)tools: <list> → omit (no Cursor equivalent; note in report). Exception: if tools lists only Read, Glob, and/or Grep (no Edit, Write, Bash, WebFetch, WebSearch), map to readonly: truemaxTurns, memory, effort, color, permissionMode → omit (note in report)Skill field mapping:
argument-hint → omit (no Cursor equivalent; note in report)@ reference conversion (applied in AGENTS.md body, subagent wrappers, and skill copies):
Replace every occurrence of @path/to/file with [filename](path/to/file) where filename is the last component of the path (e.g., @.aidocs/STRATEGY.md → [STRATEGY.md](.aidocs/STRATEGY.md)).
Show a formatted table to the user:
## Migration Plan
| Source | Target | Strategy | Notes |
|--------|--------|----------|-------|
| CLAUDE.md | AGENTS.md | markdown links hub | 2 @imports → 2 markdown links |
| .claude/agents/unit-tester.md | (none) | already Cursor-readable | no @refs in body |
| .claude/agents/refactorer.md | .cursor/agents/refactorer.md | wrapper + @→link | model: sonnet→fast; background lost; tools lost |
| .claude/skills/adr/SKILL.md | .cursor/skills/adr/SKILL.md | transformed copy | argument-hint lost; ! commands present |
Flag any:
.claude/agents/Ask the user to confirm before proceeding.
Case A — symlink detected: nothing to do.
Case B — plain CLAUDE.md, no @refs:
! ln -s CLAUDE.md AGENTS.md
Cases C/D — @imports (with or without inline content):
Create AGENTS.md by processing CLAUDE.md line by line: replace each @path/to/file with [filename](path/to/file), preserve all other content as-is.
Example (Case C, current repo):
- For general strategy guidelines read [STRATEGY.md](.aidocs/STRATEGY.md)
- For project-specific details read [PROJECT.md](.aidocs/PROJECT.md)
Only for agents whose body contains @ references (agents without @refs are already Cursor-readable from .claude/agents/):
name, description, model, background, tools@path/to/file with [filename](path/to/file).cursor/agents/<name>.md:---
name: <name>
description: <description>
[model: <mapped-value>]
[readonly: true]
---
<body with @refs converted to markdown links>
Create the .cursor/agents/ directory if it does not exist.
For each .claude/skills/<name>/SKILL.md (excluding migrate-cursor and migrate-to-cursor):
name, description. Note argument-hint loss.@path/to/file with [filename](path/to/file).cursor/skills/<name>/SKILL.md:---
name: <name>
description: <description>
---
<body with @refs converted to markdown links>
Create the .cursor/skills/<name>/ directory if it does not exist.
List every file created or skipped, and include a short caveats section:
AGENTS.md. The links serve as navigable references; Cursor must be explicitly asked to read them..claude/agents/ natively (lower priority than .cursor/agents/). Unknown Claude frontmatter fields (tools, background, etc.) are silently ignored.background, tools, maxTurns, memory, effort, color, permissionMode have no Cursor equivalent and were omitted.readonly: true, verify this is appropriate for its intended behavior..cursor/skills/ files are copies of the Claude originals, not references. Claude skill remains the source of truth — edit there and re-run migration to sync.argument-hint has no Cursor equivalent.model: values were not recognized, they were omitted.