TL;DR
Convierta un archivo de agente de IA a 10 IDEs en 3 pasos prácticos:
- Analice el frontmatter YAML con las funciones bash
get_field(),get_body()yto_kebab(). - Transforme a formatos específicos de la herramienta usando
convert.sh(Claude Code.md, Cursor.mdc, AiderCONVENTIONS.md, Windsurf.windsurfrules). - Instale en las rutas correctas con
install.sh.
Escriba una vez, convierta automáticamente, despliegue en todas partes.
Un archivo de agente. Diez IDEs. Aprenda cómo el proyecto The Agency convierte un solo archivo Markdown para que funcione en Claude Code, Cursor, Aider, Windsurf, GitHub Copilot y más de 6 herramientas adicionales.
Usted escribe un agente de IA. Ahora quiere que esté disponible en:
- Claude Code (archivos
.mden~/.claude/agents/) - Cursor (archivos
.mdcen.cursor/rules/) - Aider (un solo
CONVENTIONS.mden la raíz del proyecto) - Windsurf (un solo archivo
.windsurfrules) - GitHub Copilot (archivos
.mden~/.github/agents/) - Y más de 5 herramientas adicionales
¿Escribe 10 versiones? No. Escriba una vez, convierta automáticamente.
El proyecto The Agency resuelve esto con dos scripts bash:
-
convert.sh— Transforma los archivos del agente a formatos específicos de la herramienta -
install.sh— Copia los archivos convertidos a las rutas correctas
En este tutorial, realizará ingeniería inversa de ambos scripts. Aprenderá cómo analizar el frontmatter YAML, extraer el contenido del cuerpo y construir tuberías de conversión para cualquier herramienta.
💡 Ya sea que esté implementando agentes para flujos de trabajo de desarrollo de API con integración de Apidog o creando agentes de prueba especializados, el sistema de conversión garantiza que funcionen en todos los IDEs preferidos de su equipo.
El formato del agente
Cada agente en The Agency usa la misma estructura:
---
name: API Tester
description: "Specialized in API testing with Apidog, Postman, and automated validation"
color: purple
emoji: 🧪
vibe: Breaks APIs before users do.
---
# API Tester Agent Personality
You are **API Tester**, an expert in API validation...
## Identity & Memory
- Role: API testing specialist
- Personality: Thorough, skeptical, evidence-focused
...
El archivo tiene dos partes:
-
Frontmatter — Metadatos YAML entre delimitadores
--- -
Cuerpo — Contenido Markdown después del segundo
---
El proceso de conversión consiste en extraer campos del frontmatter, transformar el cuerpo al formato objetivo y escribirlo en la ruta correcta.
Paso 1: Analizar el Frontmatter YAML
Cree parse-frontmatter.sh:
#!/usr/bin/env bash
#
# parse-frontmatter.sh — Extrae campos YAML del frontmatter de archivos de agente
#
set -euo pipefail
# Extrae el valor de un campo del frontmatter YAML
# Uso: get_field <field> <file>
get_field() {
local field="$1" file="$2"
awk -v f="$field" '
/^---$/ { fm++; next }
fm == 1 && $0 ~ "^" f ": " {
sub("^" f ": ", "");
print;
exit
}
' "$file"
}
# Elimina el frontmatter, devuelve solo el cuerpo
# Uso: get_body <file>
get_body() {
awk 'BEGIN{fm=0} /^---$/{fm++; next} fm>=2{print}' "$1"
}
# Convierte el nombre a slug kebab-case
# Uso: to_kebab "API Tester" → api-tester
to_kebab() {
echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g'
}
# Demo
if [[ "${1:-}" == "--demo" ]]; then
AGENT_FILE="${2:-test-agent.md}"
echo "File: $AGENT_FILE"
echo "Name: $(get_field 'name' "$AGENT_FILE")"
echo "Description: $(get_field 'description' "$AGENT_FILE")"
echo "Slug: $(to_kebab "$(get_field 'name' "$AGENT_FILE")")"
echo "---"
echo "Body preview:"
get_body "$AGENT_FILE" | head -10
fi
Pruebe el script:
chmod +x parse-frontmatter.sh
./parse-frontmatter.sh --demo engineering-backend-architect.md
Salida esperada:
File: engineering-backend-architect.md
Name: Backend Architect
Description: Senior backend architect specializing in scalable system design...
Slug: backend-architect
---
Body preview:
# Backend Architect Agent Personality
You are **Backend Architect**, a senior backend architect...
Paso 2: Convertir al formato Claude Code
Claude Code usa archivos .md sin transformación. Simplemente copie:
convert_claude_code() {
local agent_file="$1"
local dest="$HOME/.claude/agents/"
mkdir -p "$dest"
cp "$agent_file" "$dest/"
echo " Claude Code: $(basename "$agent_file")"
}
Paso 3: Convertir al formato Cursor
Cursor requiere archivos .mdc con un campo description en el frontmatter:
convert_cursor() {
local agent_file="$1"
local name=$(get_field 'name' "$agent_file")
local description=$(get_field 'description' "$agent_file")
local slug=$(to_kebab "$name")
local body=$(get_body "$agent_file")
local output=".cursor/rules/agency-${slug}.mdc"
mkdir -p "$(dirname "$output")"
cat > "$output" << EOF
---
description: Agency agent: $description
---
$body
EOF
echo " Cursor: agency-${slug}.mdc"
}
Entrada ejemplo:
---
name: API Tester
description: Specialized in API testing...
---
# API Tester Agent...
Salida (.mdc):
---
description: Agency agent: Specialized in API testing...
---
# API Tester Agent...
Paso 4: Convertir al formato Aider
Aider usa un único archivo CONVENTIONS.md para todos los agentes:
convert_aider() {
local agent_file="$1"
local output="CONVENTIONS.md"
# Añadir con separador
echo "" >> "$output"
echo "---" >> "$output"
echo "" >> "$output"
cat "$agent_file" >> "$output"
echo " Aider: appended to $output"
}
Para construir el archivo completo:
build_aider() {
local output="CONVENTIONS.md"
echo "# Agency Agents for Aider" > "$output"
echo "" >> "$output"
echo "This file contains all Agency agents for Aider integration." >> "$output"
echo "" >> "$output"
for agent_file in engineering/*.md design/*.md testing/*.md; do
convert_aider "$agent_file"
done
}
Paso 5: Convertir al formato Windsurf
Windsurf usa un único archivo .windsurfrules (igual que Aider):
convert_windsurf() {
local agent_file="$1"
local output=".windsurfrules"
echo "" >> "$output"
echo "---" >> "$output"
echo "" >> "$output"
cat "$agent_file" >> "$output"
echo " Windsurf: appended to $output"
}
Paso 6: Convertir al formato Antigravity
Antigravity (Gemini) usa archivos SKILL.md en subdirectorios de habilidad:
convert_antigravity() {
local agent_file="$1"
local name=$(get_field 'name' "$agent_file")
local slug=$(to_kebab "$name")
local output="integrations/antigravity/skills/agency-${slug}/SKILL.md"
mkdir -p "$(dirname "$output")"
cat > "$output" << EOF
# Agency Agent: $name
$(get_body "$agent_file")
EOF
echo " Antigravity: agency-${slug}/SKILL.md"
}
Paso 7: Convertir al formato OpenClaw
OpenClaw requiere tres archivos por agente:
convert_openclaw() {
local agent_file="$1"
local name=$(get_field 'name' "$agent_file")
local description=$(get_field 'description' "$agent_file")
local slug=$(to_kebab "$name")
local body=$(get_body "$agent_file")
local output_dir="integrations/openclaw/agency-${slug}"
mkdir -p "$output_dir"
# SOUL.md
cat > "$output_dir/SOUL.md" << EOF
# $name
$description
---
$body
EOF
# AGENTS.md
cat > "$output_dir/AGENTS.md" << EOF
# Agent Capabilities: $name
- Specialized expertise in domain
- Deliverable-focused output
- Success metrics defined
See SOUL.md for full definition.
EOF
# IDENTITY.md
cat > "$output_dir/IDENTITY.md" << EOF
# Identity: $name
- Name: $name
- Description: $description
- Source: The Agency (agency-agents repo)
EOF
echo " OpenClaw: agency-${slug}/"
}
Paso 8: Script completo convert.sh
Ejemplo simplificado de convert.sh:
#!/usr/bin/env bash
#
# convert.sh — Convierte todos los agentes a formatos específicos
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
OUT_DIR="$REPO_ROOT/integrations"
# Frontmatter helpers
get_field() {
local field="$1" file="$2"
awk -v f="$field" '
/^---$/ { fm++; next }
fm == 1 && $0 ~ "^" f ": " { sub("^" f ": ", ""); print; exit }
' "$file"
}
get_body() {
awk 'BEGIN{fm=0} /^---$/{fm++; next} fm>=2{print}' "$1"
}
to_kebab() {
echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g'
}
# Funciones de conversión
convert_claude_code() {
local agent_file="$1"
local dest="$OUT_DIR/claude-code/"
mkdir -p "$dest"
cp "$agent_file" "$dest/"
}
convert_cursor() {
local agent_file="$1"
local name=$(get_field 'name' "$agent_file")
local slug=$(to_kebab "$name")
local body=$(get_body "$agent_file")
mkdir -p "$OUT_DIR/cursor/.cursor/rules/"
cat > "$OUT_DIR/cursor/.cursor/rules/agency-${slug}.mdc" << EOF
---
description: Agency agent: $(get_field 'description' "$agent_file")
---
$body
EOF
}
convert_aider() {
local output="$OUT_DIR/aider/CONVENTIONS.md"
echo "" >> "$output"
echo "---" >> "$output"
cat "$agent_file" >> "$output"
}
convert_windsurf() {
local output="$OUT_DIR/windsurf/.windsurfrules"
echo "" >> "$output"
echo "---" >> "$output"
cat "$agent_file" >> "$output"
}
# Bucle principal
echo "Convirtiendo agentes..."
AGENT_DIRS=(engineering design testing marketing sales)
for dir in "${AGENT_DIRS[@]}"; do
for agent_file in "$REPO_ROOT/$dir"/*.md; do
[[ -f "$agent_file" ]] || continue
name=$(get_field 'name' "$agent_file")
echo "Procesando: $name"
convert_claude_code "$agent_file"
convert_cursor "$agent_file"
done
done
# Archivos combinados
echo "# Agency Agents for Aider" > "$OUT_DIR/aider/CONVENTIONS.md"
for dir in "${AGENT_DIRS[@]}"; do
for agent_file in "$REPO_ROOT/$dir"/*.md; do
[[ -f "$agent_file" ]] || continue
convert_aider "$agent_file"
done
done
echo "# Agency Agents for Windsurf" > "$OUT_DIR/windsurf/.windsurfrules"
for dir in "${AGENT_DIRS[@]}"; do
for agent_file in "$REPO_ROOT/$dir"/*.md; do
[[ -f "$agent_file" ]] || continue
convert_windsurf "$agent_file"
done
done
echo "Conversión completa!"
echo " Claude Code: $OUT_DIR/claude-code/"
echo " Cursor: $OUT_DIR/cursor/.cursor/rules/"
echo " Aider: $OUT_DIR/aider/CONVENTIONS.md"
echo " Windsurf: $OUT_DIR/windsurf/.windsurfrules"
Ejecute:
chmod +x convert.sh
./convert.sh
Paso 9: Instalar en cada herramienta
Después de la conversión, copie los archivos a las rutas específicas:
#!/usr/bin/env bash
#
# install.sh — Instala agentes convertidos en tus herramientas locales
#
set -euo pipefail
# Claude Code
install_claude_code() {
local src="$REPO_ROOT/integrations/claude-code/"
local dest="$HOME/.claude/agents/"
mkdir -p "$dest"
cp "$src"/*.md "$dest/"
echo "Claude Code: $(find "$dest" -name '*.md' | wc -l) agentes instalados"
}
# Cursor
install_cursor() {
local src="$REPO_ROOT/integrations/cursor/.cursor/rules/"
local dest="./.cursor/rules/"
mkdir -p "$dest"
cp "$src"/*.mdc "$dest/"
echo "Cursor: $(find "$dest" -name '*.mdc' | wc -l) reglas instaladas"
}
# Aider
install_aider() {
local src="$REPO_ROOT/integrations/aider/CONVENTIONS.md"
local dest="./CONVENTIONS.md"
cp "$src" "$dest"
echo "Aider: CONVENTIONS.md instalado"
}
# Windsurf
install_windsurf() {
local src="$REPO_ROOT/integrations/windsurf/.windsurfrules"
local dest="./.windsurfrules"
cp "$src" "$dest"
echo "Windsurf: .windsurfrules instalado"
}
# Instala todas las herramientas detectadas
install_all() {
if [[ -d "$HOME/.claude/agents/" ]]; then
install_claude_code
fi
if command -v cursor &>/dev/null || [[ -d "./.cursor/" ]]; then
install_cursor
fi
if command -v aider &>/dev/null; then
install_aider
fi
}
install_all
Comparación de formatos
| Herramienta | Formato | Alcance | Conversión |
|---|---|---|---|
| Claude Code | .md |
De usuario (~/.claude/agents/) |
Copiar tal cual |
| Cursor | .mdc |
Proyecto (.cursor/rules/) |
Añadir frontmatter de descripción |
| Aider | CONVENTIONS.md |
Raíz del proyecto | Concatenar todos los agentes |
| Windsurf | .windsurfrules |
Raíz del proyecto | Concatenar todos los agentes |
| GitHub Copilot | .md |
~/.github/agents/ |
Copiar tal cual |
| Antigravity | SKILL.md |
~/.gemini/antigravity/ |
Envolver en directorio de habilidad |
| OpenClaw |
SOUL.md + otros |
~/.openclaw/ |
Dividir en 3 archivos |
| Gemini CLI | Extensión | ~/.gemini/extensions/ |
Generar manifiesto + habilidades |
| OpenCode | .md |
.opencode/agents/ |
Copiar tal cual |
| Qwen Code | .md |
.qwen/agents/ |
Copiar como SubAgente |
Construya su propio script de conversión
Plantilla para añadir una nueva herramienta:
#!/usr/bin/env bash
# 1. Defina la función de conversión
convert_your_tool() {
local agent_file="$1"
local name=$(get_field 'name' "$agent_file")
local description=$(get_field 'description' "$agent_file")
local slug=$(to_kebab "$name")
local body=$(get_body "$agent_file")
# 2. Ruta de salida
local output="path/to/your/tool/agency-${slug}.ext"
mkdir -p "$(dirname "$output")"
# 3. Escriba el contenido convertido
cat > "$output" << EOF
# Formato específico de su herramienta
# Use: $name, $description, $body
EOF
echo " YourTool: agency-${slug}.ext"
}
# 4. Añada al bucle principal
for agent_file in engineering/*.md; do
convert_your_tool "$agent_file"
done
Lo que ha construido
| Componente | Propósito |
|---|---|
get_field() |
Extraer valores del frontmatter YAML |
get_body() |
Quitar el frontmatter, devolver el cuerpo |
to_kebab() |
Convertir nombres a slugs URL-seguros |
convert_cursor() |
Transformar al formato .mdc
|
convert_aider() |
Concatenar en un solo archivo |
convert_windsurf() |
Concatenar en un solo archivo |
convert_antigravity() |
Crear directorios de habilidad |
convert_openclaw() |
Dividir en 3 archivos por agente |
install.sh |
Copiar a rutas específicas de la herramienta |
Próximos pasos
Extienda los scripts:
- Añada conversión paralela con
xargs -Po GNU parallel - Añada validación (comprobar campos de frontmatter requeridos)
- Añada modo de prueba (
--dry-runflag)
Añada más herramientas:
- Extensiones de VS Code
- IDEs de JetBrains
- Herramientas internas personalizadas
Optimice para grandes repositorios:
- Cachear frontmatter analizado
- Usar
findcon-print0para manejo seguro de archivos - Añadir barras de progreso para más de 100 agentes
Solución de problemas comunes
El script de conversión falla con "bad substitution":
- Asegúrese de estar usando bash:
#!/usr/bin/env bash - Compruebe la versión:
bash --version(debe ser 4.0+) - Ejecute explícitamente con bash:
bash convert.sh - Elimine finales de línea de Windows:
sed -i 's/\r$//' convert.sh
Los campos del frontmatter no se extraen:
- El formato YAML debe usar
:(dos puntos espacio) - No debe haber espacios extra antes de los campos
- Delimitadores exactos:
--- - Pruebe manualmente:
./parse-frontmatter.sh --demo agent.md
La generación de slugs crea nombres rotos:
- Pruebe
to_kebab()con casos extremos - Maneje caracteres especiales:
to_kebab() { echo "$1" | iconv -f utf8 -t ascii//translit | ... } - Fallback para slugs vacíos:
[[ -z "$slug" ]] && slug="unknown-agent" - Registre los nombres originales para depuración
Las reglas del cursor no se cargan:
- Asegúrese de que
.mdctengadescriptionen el frontmatter - Revise
.cursor/mcp.json - Los archivos deben estar en
.cursor/rules/ - Reinicie Cursor tras añadir reglas nuevas
El archivo CONVENTIONS.md de Aider es demasiado grande:
- Divida por categoría:
CONVENTIONS-engineering.md, etc. - Poda automática para agentes obsoletos
- Añada tabla de contenidos
- Considere archivos por agente con directivas de inclusión
Optimización del rendimiento para grandes conversiones
Procesamiento paralelo:
Use GNU parallel para grandes volúmenes:
#!/usr/bin/env bash
# convert-parallel.sh
export OUT_DIR="$REPO_ROOT/integrations"
# Exportar funciones para parallel
export -f get_field get_body to_kebab convert_cursor convert_claude_code
find "$REPO_ROOT" -name "*.md" -type f | \
parallel -j 8 --progress '
name=$(get_field "name" {})
slug=$(to_kebab "$name")
echo "Convirtiendo: $name"
convert_cursor "{}"
convert_claude_code "{}"
'
echo "Conversión paralela completada!"
Conversión incremental:
Solo procese archivos modificados:
#!/usr/bin/env bash
# convert-incremental.sh
CACHE_FILE="$REPO_ROOT/.conversion-cache"
declare -A PREV_HASHES
if [[ -f "$CACHE_FILE" ]]; then
while IFS='=' read -r file hash; do
PREV_HASHES["$file"]="$hash"
done < "$CACHE_FILE"
fi
for agent_file in engineering/*.md; do
CURRENT_HASH=$(md5sum "$agent_file" | cut -d' ' -f1)
PREV_HASH="${PREV_HASHES[$agent_file]:-}"
if [[ "$CURRENT_HASH" != "$PREV_HASH" ]]; then
echo "Cambiado: $agent_file"
convert_cursor "$agent_file"
convert_claude_code "$agent_file"
NEW_HASHES["$agent_file"]="$CURRENT_HASH"
else
echo "Sin cambios: $agent_file"
fi
done
for file in "${!NEW_HASHES[@]}"; do
echo "$file=${NEW_HASHES[$file]}"
done > "$CACHE_FILE"
Barra de progreso:
Para conversiones largas:
#!/usr/bin/env bash
total_files=$(find "$REPO_ROOT" -name "*.md" -type f | wc -l)
current=0
for agent_file in "$REPO_ROOT"/**/*.md; do
((current++))
percent=$((current * 100 / total_files))
# Barra de progreso
filled=$((percent / 5))
empty=$((20 - filled))
bar=$(printf '%*s' "$filled" | tr ' ' '#')
spaces=$(printf '%*s' "$empty" | tr ' ' ' ')
name=$(get_field 'name' "$agent_file")
echo -ne "\r[${bar}${spaces}] ${percent}% - $name"
convert_cursor "$agent_file"
done
echo -ne "\n"
Consideraciones de seguridad para agentes compartidos
Validación de fuentes de agentes:
Al descargar agentes externos:
#!/usr/bin/env bash
# validate-agent.sh
validate_agent() {
local file="$1"
# Verifica campos requeridos
local name=$(get_field 'name' "$file")
local description=$(get_field 'description' "$file")
if [[ -z "$name" ]]; then
echo "ERROR: Falta campo 'name' en $file"
return 1
fi
if [[ -z "$description" ]]; then
echo "WARNING: Falta campo 'description' en $file"
fi
# Busca patrones peligrosos
local body=$(get_body "$file")
if echo "$body" | grep -q 'rm -rf\|curl.*\|wget.*\|eval\|exec'; then
echo "WARNING: Patrones potencialmente peligrosos en $file"
return 1
fi
echo "VALIDO: $name"
return 0
}
Ejecución de agentes en sandbox:
- Use contenedores Docker para ejecución aislada
- Limite acceso al sistema de archivos (montaje solo lectura)
- Restrinja red a dominios específicos
- Registre todas las acciones para auditoría
Un archivo de agente. Diez IDEs. Dos scripts bash.
Esa es la fuerza de la automatización de conversión. Escriba una vez, convierta automáticamente, instale en todas partes.
Ahora es su turno: añada soporte de conversión para su herramienta de IA favorita. Comparta el script. Haga que los agentes sean portátiles.
Puntos clave
- Escriba una vez, convierta a más de 10 formatos — Un solo archivo Markdown con frontmatter YAML se transforma a Claude Code, Cursor, Aider, Windsurf y más de 6 herramientas adicionales.
-
El análisis de Bash maneja la extracción del frontmatter —
get_field()extrae valores YAML,get_body()quita el frontmatter,to_kebab()crea slugs seguros para URL. - Los formatos específicos de la herramienta requieren diferentes transformaciones — Claude Code copia tal cual, Cursor añade frontmatter de descripción, Aider/Windsurf concatenan todos los agentes.
-
Los scripts de instalación copian a las rutas correctas — Las herramientas de usuario usan
~/.claude/agents/, las de proyecto usan.cursor/rules/o archivos en la raíz del proyecto. -
Extienda con plantillas para nuevas herramientas — Defina la función
convert_your_tool(), añádala al bucle principal y documente los requisitos del formato.
Preguntas frecuentes
¿Qué es convert.sh y cómo funciona?
convert.sh es un script bash que analiza el frontmatter YAML de los archivos Markdown de los agentes, extrae el contenido del cuerpo y transforma cada agente a formatos específicos de la herramienta. Utiliza awk para el análisis, sed para la conversión de slugs y heredocs para la generación de salida.
¿Cómo funciona el análisis del frontmatter en bash?
La función get_field() utiliza awk para rastrear los delimitadores del frontmatter (---), encuentra la línea que coincide con el nombre del campo y extrae el valor. get_body() imprime todas las líneas después del segundo delimitador ---.
¿Qué IDEs y herramientas son compatibles?
Claude Code (.md), Cursor (.mdc), Aider (CONVENTIONS.md), Windsurf (.windsurfrules), GitHub Copilot (.md), Antigravity (SKILL.md), OpenClaw (SOUL.md + 2 archivos), extensiones de Gemini CLI, OpenCode y Qwen Code.
¿Cómo añado soporte de conversión para una nueva herramienta?
Cree una función convert_yourtool() que extraiga los campos del frontmatter, transforme el cuerpo al formato de su herramienta y escriba en la ruta correcta. Añada la llamada a la función al bucle de conversión principal.
¿Puedo ejecutar conversiones en paralelo para un procesamiento más rápido?
Sí. Utilice xargs -P o GNU parallel para procesar varios archivos de agentes simultáneamente. Para más de 100 agentes, la conversión en paralelo puede reducir el tiempo de ejecución de minutos a segundos.
¿Cómo valido que los campos del frontmatter existen?
Añada comprobaciones de validación en su función de conversión: [[ -z "$name" ]] && echo "Missing name field" && exit 1. Ejecute la validación antes de escribir los archivos de salida.
¿Qué pasa si la conversión falla para algunos agentes?
Use set -euo pipefail para fallar rápidamente en caso de errores. Añada manejo de errores con || continue para omitir archivos dañados. Registre los fallos en un archivo separado para depuración.
Top comments (0)