DEV Community

Cover image for Como Converter um Agente de IA para Trabalhar em 10 IDEs Diferentes
Lucas
Lucas

Posted on • Originally published at apidog.com

Como Converter um Agente de IA para Trabalhar em 10 IDEs Diferentes

TL;DR

Converta um arquivo de agente de IA para 10 IDEs em 3 etapas:

(1) Analise o frontmatter YAML com as funções bash get_field(), get_body() e to_kebab()

(2) Transforme para formatos específicos de ferramentas usando convert.sh (Claude Code .md, Cursor .mdc, Aider CONVENTIONS.md, Windsurf .windsurfrules)

(3) Instale nos caminhos corretos com install.sh.

Escreva uma vez, converta automaticamente, implante em todo lugar.

Um arquivo de agente. Dez IDEs. Aprenda como o projeto The Agency converte um único arquivo Markdown para funcionar com Claude Code, Cursor, Aider, Windsurf, GitHub Copilot e mais de 6 outras ferramentas.

Experimente o Apidog hoje

Você escreve um agente de IA. Agora você quer ele disponível em:

  • Claude Code (arquivos .md em ~/.claude/agents/)
  • Cursor (arquivos .mdc em .cursor/rules/)
  • Aider (um único CONVENTIONS.md na raiz do projeto)
  • Windsurf (um único arquivo .windsurfrules)
  • GitHub Copilot (arquivos .md em ~/.github/agents/)
  • E mais de 5 outras ferramentas

Você escreve 10 versões? Não. Você escreve uma vez, converte automaticamente.

O projeto The Agency resolve isso com dois scripts bash:

  • convert.sh — Transforma arquivos de agente em formatos específicos de ferramentas
  • install.sh — Copia arquivos convertidos para os caminhos corretos

Neste tutorial, você fará engenharia reversa de ambos os scripts. Você aprenderá como analisar frontmatter YAML, extrair conteúdo do corpo e construir pipelines de conversão para qualquer ferramenta.

💡 Seja você implantando agentes para fluxos de trabalho de desenvolvimento de API com integração Apidog ou criando agentes de teste especializados, o sistema de conversão garante que eles funcionem em todas as IDEs preferidas da sua equipe.

O Formato do Agente

Cada agente na The Agency usa a mesma estrutura:

---
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
...
Enter fullscreen mode Exit fullscreen mode

O arquivo tem duas partes:

  1. Frontmatter — Metadados YAML entre delimitadores ---
  2. Corpo — Conteúdo Markdown após o segundo ---

O que converter significa: extrair campos do frontmatter, transformar o corpo para o formato alvo, escrever no caminho correto.

Etapa 1: Analisar o Frontmatter YAML

Crie parse-frontmatter.sh:

#!/usr/bin/env bash
#
# parse-frontmatter.sh — Extract YAML frontmatter fields from agent files
#

set -euo pipefail

# Extrai um campo do frontmatter YAML
get_field() {
  local field="$1" file="$2"
  awk -v f="$field" '
    /^---$/ { fm++; next }
    fm == 1 && $0 ~ "^" f ": " {
      sub("^" f ": ", "");
      print;
      exit
    }
  ' "$file"
}

# Remove o frontmatter, retorna só o corpo
get_body() {
  awk 'BEGIN{fm=0} /^---$/{fm++; next} fm>=2{print}' "$1"
}

# Converte nome para slug kebab-case
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
Enter fullscreen mode Exit fullscreen mode

Teste:

chmod +x parse-frontmatter.sh
./parse-frontmatter.sh --demo engineering-backend-architect.md
Enter fullscreen mode Exit fullscreen mode

Saída 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...
Enter fullscreen mode Exit fullscreen mode

Etapa 2: Converter para o Formato Claude Code

Claude Code usa arquivos .md brutos. Não precisa converter, só copiar:

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")"
}
Enter fullscreen mode Exit fullscreen mode

Etapa 3: Converter para o Formato Cursor

Cursor exige arquivos .mdc com description no 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"
}
Enter fullscreen mode Exit fullscreen mode

Exemplo de entrada:

---
name: API Tester
description: Specialized in API testing...
---

# API Tester Agent...
Enter fullscreen mode Exit fullscreen mode

Exemplo de saída (.mdc):

---
description: Agency agent: Specialized in API testing...
---

# API Tester Agent...
Enter fullscreen mode Exit fullscreen mode

Etapa 4: Converter para o Formato Aider

Aider usa um único arquivo CONVENTIONS.md com todos os agentes:

convert_aider() {
  local agent_file="$1"
  local output="CONVENTIONS.md"

  echo "" >> "$output"
  echo "---" >> "$output"
  echo "" >> "$output"
  cat "$agent_file" >> "$output"

  echo "  Aider: appended to $output"
}
Enter fullscreen mode Exit fullscreen mode

Crie o arquivo com todos os agentes:

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
}
Enter fullscreen mode Exit fullscreen mode

Etapa 5: Converter para o Formato Windsurf

Windsurf usa um único arquivo .windsurfrules:

convert_windsurf() {
  local agent_file="$1"
  local output=".windsurfrules"

  echo "" >> "$output"
  echo "---" >> "$output"
  echo "" >> "$output"
  cat "$agent_file" >> "$output"

  echo "  Windsurf: appended to $output"
}
Enter fullscreen mode Exit fullscreen mode

Etapa 6: Converter para o Formato Antigravity

Antigravity (Gemini) usa arquivos SKILL.md em subdiretórios próprios:

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"
}
Enter fullscreen mode Exit fullscreen mode

Etapa 7: Converter para o Formato OpenClaw

OpenClaw usa três arquivos 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 - Definição principal
  cat > "$output_dir/SOUL.md" << EOF
# $name

$description

---

$body
EOF

  # AGENTS.md - Capacidades do agente
  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 - Identidade do agente
  cat > "$output_dir/IDENTITY.md" << EOF
# Identity: $name

- Name: $name
- Description: $description
- Source: The Agency (agency-agents repo)
EOF

  echo "  OpenClaw: agency-${slug}/"
}
Enter fullscreen mode Exit fullscreen mode

Etapa 8: O Script convert.sh Completo

Script de conversão completo para todos os formatos principais:

#!/usr/bin/env bash
#
# convert.sh — Convert all Agency agents to tool-specific formats
#

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'
}

# Conversion functions
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"
}

# Main conversion loop
echo "Converting Agency agents..."

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 "Processing: $name"

    convert_claude_code "$agent_file"
    convert_cursor "$agent_file"
  done
done

# Build combined files
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 "Conversion complete!"
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"
Enter fullscreen mode Exit fullscreen mode

Execute:

chmod +x convert.sh
./convert.sh
Enter fullscreen mode Exit fullscreen mode

Etapa 9: Instalar em Cada Ferramenta

Após converter, copie os arquivos para os locais de cada ferramenta:

#!/usr/bin/env bash
#
# install.sh — Install converted agents to your local tools
#

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) agents installed"
}

# 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) rules installed"
}

# Aider
install_aider() {
  local src="$REPO_ROOT/integrations/aider/CONVENTIONS.md"
  local dest="./CONVENTIONS.md"
  cp "$src" "$dest"
  echo "Aider: CONVENTIONS.md installed"
}

# Windsurf
install_windsurf() {
  local src="$REPO_ROOT/integrations/windsurf/.windsurfrules"
  local dest="./.windsurfrules"
  cp "$src" "$dest"
  echo "Windsurf: .windsurfrules installed"
}

# Instala em todas as ferramentas 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
Enter fullscreen mode Exit fullscreen mode

Comparação de Formatos

Ferramenta Formato Escopo Conversão
Claude Code .md Global (~/.claude/agents/) Copia como está
Cursor .mdc Projeto (.cursor/rules/) Adiciona frontmatter de descrição
Aider CONVENTIONS.md Raiz do projeto Concatena todos os agentes
Windsurf .windsurfrules Raiz do projeto Concatena todos os agentes
GitHub Copilot .md Global (~/.github/agents/) Copia como está
Antigravity SKILL.md Global (~/.gemini/antigravity/) Empacota em diretório da skill
OpenClaw SOUL.md + outros Global (~/.openclaw/) Divide em 3 arquivos
Gemini CLI Extensão Global (~/.gemini/extensions/) Gera manifesto + habilidades
OpenCode .md Projeto (.opencode/agents/) Copia como está
Qwen Code .md Projeto (.qwen/agents/) Copia como SubAgente

Crie Seu Próprio Script de Conversão

Modelo para adicionar uma nova ferramenta:

#!/usr/bin/env bash

# 1. Defina a função de conversão
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. Crie o caminho de saída
  local output="path/to/your/tool/agency-${slug}.ext"
  mkdir -p "$(dirname "$output")"

  # 3. Escreva o conteúdo convertido
  cat > "$output" << EOF
# Seu formato específico da ferramenta
# Use: $name, $description, $body
EOF

  echo "  YourTool: agency-${slug}.ext"
}

# 4. Adicione ao loop principal
for agent_file in engineering/*.md; do
  convert_your_tool "$agent_file"
done
Enter fullscreen mode Exit fullscreen mode

O Que Você Construiu

Componente Propósito
get_field() Extrair valores do frontmatter YAML
get_body() Remover frontmatter, retorna corpo markdown
to_kebab() Converter nomes para slugs seguros para URL
convert_cursor() Transformar para formato .mdc
convert_aider() Concatenar em um único arquivo
convert_windsurf() Concatenar em um único arquivo
convert_antigravity() Criar diretórios de habilidades
convert_openclaw() Dividir em 3 arquivos por agente
install.sh Copiar para caminhos específicos da ferramenta

Próximos Passos

Estenda os scripts:

  • Adicione conversão paralela com xargs -P ou GNU parallel
  • Adicione validação (verifique campos de frontmatter obrigatórios)
  • Adicione modo de simulação (--dry-run flag)

Adicione mais ferramentas:

  • Extensões do VS Code
  • IDEs JetBrains
  • Ferramentas internas personalizadas

Otimize para grandes repositórios:

  • Armazene em cache o frontmatter analisado
  • Use find com -print0 para manipulação segura de arquivos
  • Adicione barras de progresso para mais de 100 agentes

Solução de Problemas Comuns

O script de conversão falha com "bad substitution":

  • Certifique-se de usar bash: #!/usr/bin/env bash
  • Verifique a versão do bash: bash --version (4.0+)
  • Execute explicitamente: bash convert.sh
  • Remova quebras de linha do Windows: sed -i 's/\r$//' convert.sh

Campos do frontmatter não extraem:

  • Use : (dois pontos + espaço) no YAML
  • Verifique espaços extras antes dos campos
  • Delimitadores do frontmatter devem ser ---
  • Teste manualmente: ./parse-frontmatter.sh --demo agent.md

Slugs quebrados:

  • Teste to_kebab() com vários nomes
  • Lide com caracteres especiais: to_kebab() { echo "$1" | iconv -f utf8 -t ascii//translit | ... }
  • Adicione fallback: [[ -z "$slug" ]] && slug="unknown-agent"
  • Logue nomes originais para debug

Regras do Cursor não carregam:

  • Arquivos .mdc precisam de frontmatter válido com description
  • Verifique .cursor/mcp.json
  • Certifique-se de que os arquivos estão em .cursor/rules/
  • Reinicie o Cursor após adicionar regras

CONVENTIONS.md do Aider fica grande:

  • Divida por categoria: CONVENTIONS-engineering.md, etc
  • Implemente poda de agentes obsoletos
  • Adicione índice no topo
  • Considere arquivos por agente com diretivas de inclusão

Otimização de Desempenho para Grandes Conversões

Processamento Paralelo (GNU parallel):

#!/usr/bin/env bash
# convert-parallel.sh

export OUT_DIR="$REPO_ROOT/integrations"
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 "Converting: $name"
    convert_cursor "{}"
    convert_claude_code "{}"
  '

echo "Parallel conversion complete!"
Enter fullscreen mode Exit fullscreen mode

Conversão Incremental:

#!/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 "Changed: $agent_file"
    convert_cursor "$agent_file"
    convert_claude_code "$agent_file"
    NEW_HASHES["$agent_file"]="$CURRENT_HASH"
  else
    echo "Unchanged: $agent_file"
  fi
done

for file in "${!NEW_HASHES[@]}"; do
  echo "$file=${NEW_HASHES[$file]}"
done > "$CACHE_FILE"
Enter fullscreen mode Exit fullscreen mode

Barra de Progresso:

#!/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))

  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"
Enter fullscreen mode Exit fullscreen mode

Considerações de Segurança para Agentes Compartilhados

Valide agentes baixados:

#!/usr/bin/env bash
# validate-agent.sh

validate_agent() {
  local file="$1"

  local name=$(get_field 'name' "$file")
  local description=$(get_field 'description' "$file")

  if [[ -z "$name" ]]; then
    echo "ERROR: Missing 'name' field in $file"
    return 1
  fi

  if [[ -z "$description" ]]; then
    echo "WARNING: Missing 'description' field in $file"
  fi

  local body=$(get_body "$file")

  if echo "$body" | grep -q 'rm -rf\|curl.*\|wget.*\|eval\|exec'; then
    echo "WARNING: Potentially dangerous patterns in $file"
    return 1
  fi

  echo "VALID: $name"
  return 0
}
Enter fullscreen mode Exit fullscreen mode

Execução em Sandbox:

  • Use Docker para isolar agentes não confiáveis
  • Monte diretórios como somente leitura
  • Restrinja a rede a domínios específicos
  • Logue todas as ações do agente

Um arquivo de agente. Dez IDEs. Dois scripts bash.

Automatize: escreva uma vez, converta automaticamente, instale em todo lugar.

Sua vez: adicione suporte para sua ferramenta de IA favorita. Compartilhe o script. Torne agentes portáteis.

Principais Conclusões

  • Escreva uma vez, converta para 10+ formatos — Um único arquivo Markdown com frontmatter YAML se transforma em Claude Code, Cursor, Aider, Windsurf e mais de 6 outras ferramentas
  • Parsing Bash cobre extração de frontmatterget_field() extrai valores YAML, get_body() remove o frontmatter, to_kebab() cria slugs seguros
  • Formatos diferentes exigem transformações específicas — Claude Code copia, Cursor adiciona descrição, Aider/Windsurf concatenam tudo
  • Scripts de instalação copiam para os locais certos — Ferramentas globais usam ~/.claude/agents/, ferramentas de projeto usam .cursor/rules/ ou arquivos raiz
  • Extensível para novas ferramentas — Defina a função convert_your_tool(), adicione ao loop, documente o formato

FAQ

O que é convert.sh e como ele funciona?

convert.sh é um script bash que analisa o frontmatter YAML de arquivos Markdown de agente, extrai o corpo e converte cada agente para formatos específicos de ferramenta. Usa awk para parsing, sed para slugs e heredocs para geração.

Como funciona a análise de frontmatter em bash?

get_field() usa awk para encontrar o campo pelo nome entre delimitadores ---. get_body() retorna tudo depois do segundo ---.

Quais IDEs e ferramentas são suportadas?

Claude Code (.md), Cursor (.mdc), Aider (CONVENTIONS.md), Windsurf (.windsurfrules), GitHub Copilot (.md), Antigravity (SKILL.md), OpenClaw (SOUL.md + outros), Gemini CLI, OpenCode, Qwen Code.

Como adiciono suporte para uma nova ferramenta?

Crie convert_yourtool() que extrai campos do frontmatter, converte o corpo e grava no local correto. Adicione ao loop principal.

Posso rodar conversão em paralelo?

Sim, use xargs -P ou GNU parallel para processar vários arquivos ao mesmo tempo.

Como valido campos do frontmatter?

Adicione checagens na função de conversão:

[[ -z "$name" ]] && echo "Missing name field" && exit 1

E se a conversão falhar para alguns agentes?

Use set -euo pipefail. Adicione || continue para pular arquivos com erro. Logue falhas para depuração.

Top comments (0)