🎯O que você ganha aqui
Entender exatamente o que muda em uma skill ao portar do Claude pro Codex — onde fica, o que precisa adaptar, e como o sidecar openai.yaml resolve o problema de MCP deps + branding.
Conteúdo detalhado
📦 Skill no Codex — .agents/skills/ não .codex/skills/
Esta é a primeira coisa que confunde. Quem vem do Claude pensa: ".claude/skills/ no Claude → .codex/skills/ no Codex". Errado. Skill mora em .agents/skills/.
Por que .agents/ e não .codex/
.agents/ é a convenção da spec aberta Agent Skills (agentskills.io). Qualquer tool que respeita a spec lê de lá. Codex apenas obedece a convenção, em vez de inventar caminho próprio.
Resultado: sua skill em .agents/skills/ funciona no Codex hoje, e funciona em Cursor/Gemini/qualquer tool compatível amanhã, sem mover arquivo.
Paths corretos
~/.agents/skills/<nome>/ ← global (suas skills) ./.agents/skills/<nome>/ ← projeto (skills do repo) # NÃO existe: .codex/skills/ ← Codex não enxerga .codex/agents/skills/ ← idem
⚠️Sintoma do erro
"Coloquei a skill, mas $minha-skill não dispara." → Verifica primeiro o PATH. Provavelmente está em .codex/skills/. Move pra .agents/skills/, dá refresh no Codex, volta a funcionar.
Conceitos-chave
Path obrigatório
agentskills.io
Outras tools leem
Plugins → reload
📝 SKILL.md — quase idêntico ao do Claude
O arquivo SKILL.md em si é praticamente o mesmo. Por isso a spec funciona: frontmatter YAML com name e description, corpo em markdown. Essas são as 4 coisas que sempre coincidem.
SKILL.md no Codex
--- name: revisar-pr description: Use when the user asks to review a PR or diff. --- # Revisar PR ## Passo a passo 1. Identifica a PR 2. Lê diff completo 3. Verifica bugs/edge cases/security 4. Retorna findings categorizados
✓ O que SEMPRE funciona
- • Frontmatter
name+description - • Body em markdown padrão
- • Pastas
scripts/,references/,assets/ - • Referências relativas (
./references/x.md) - • Headings, listas, code blocks
✗ O que NÃO porta
- •
allowed-toolsno frontmatter (ignorado) - •
disable-model-invocation(ignorado) - • Backtick-bang
`!cmd`(vira texto) - • Description > 8KB (truncada silenciosamente)
- •
model: opusno frontmatter (não respeitado)
💡Os 4 pilares portáveis
A spec Agent Skills define exatamente 4 coisas como comuns: nome do arquivo (SKILL.md), os campos name e description, corpo markdown, convenção de pastas. Mantém sua skill nesses 4 pilares e ela vai pro outro runtime sem dor.
Conceitos-chave
Spec comum
Sem extensão custom
scripts/refs/assets
Que viram sidecar
📎 O sidecar agents/openai.yaml
Aqui mora o detalhe que mais peculiariza o Codex: tudo que é específico do runtime (branding pra UI, MCP server dependencies, flags de comportamento) vai num arquivo separado — agents/openai.yaml dentro da pasta da skill.
Estrutura completa com sidecar
.agents/skills/minha-skill/ ├── SKILL.md ← obrigatório (spec) ├── agents/ │ └── openai.yaml ← SIDECAR do Codex ├── scripts/ ├── references/ └── assets/
Exemplo de openai.yaml
# Branding pra UI do Codex branding: display_name: "Revisar PR" icon: "🔍" category: "code-review" # MCP servers requeridos pela skill mcp_servers: - name: github command: npx args: ["-y", "@modelcontextprotocol/server-github"] env: GITHUB_TOKEN: "${GITHUB_TOKEN}" # Flags de comportamento hidden: false require_confirmation: true
Branding
Display name, ícone, categoria. Aparece na UI. Sem isso, fica genérico.
MCP deps
Skill declara MCPs que precisa. Instalação fica turn-key.
Flags
Hidden, require_confirmation, etc. Comportamento por skill.
É opcional
Sem openai.yaml a skill funciona. Só perde refinamentos: sem ícone na UI, branding genérico, MCP deps precisam ser instaladas à mão fora da skill. Com sidecar, experiência fica polida.
Conceitos-chave
Metadata separada
Skill roda sem
Declara dependência
Ícone, nome
📏 O limite oculto da description (~8K)
O Codex tem um limite não-documentado de cerca de 8.000 caracteres para a description quando indexada no catálogo. Acima disso, description é truncada — e sua skill perde os triggers que estão no fim.
🚨O cenário perigoso
- Você cria skill no Claude com description grande (15KB) — funciona bem lá
- Porta direto pro Codex
- Codex trunca em ~8K. Os triggers no fim somem.
- Skill aparenta funcionar (ainda dispara em alguns prompts), mas perde casos
- Você nunca descobre porque não dá erro — é silencioso
Técnica de front-loading
Coloque triggers e exemplos mais importantes nos primeiros 1-2KB. O resto pode vir depois (e pode ser cortado sem dor).
// CERTO — triggers no topo description: | Use when reviewing PRs. Triggers: "revisa PR", "review pull request", "code review". Examples: "revisa PR #123", "review da branch atual". More context (pode ser truncado): ... // ERRADO — triggers no fim description: | This skill specializes in deep technical code review with focus on correctness, security, and edge cases. It analyzes pull requests by reading the full diff and ... [muito mais texto] ... Triggers: "revisa PR" ← truncado, nunca alcança
🦜Polyskill antecipa
O adapter Codex do polyskill automaticamente faz front-loading: pega os triggers da description portable e move pro topo na hora de emitir pro Codex. Você não pensa nisso.
Conceitos-chave
Não-documentado
Sem erro
Triggers no topo
Resolve no build
🚫 Sem backtick-bang nativo — como contornar
Codex não interpreta `!cmd` (backtick-bang) como execução shell pré-prompt. Skill que depende disso pra injetar contexto dinâmico (status do git, log atual, branch) precisa adaptação.
🔷 Claude (original)
Branch: `!git branch --show-current` Último commit: `!git log -1 --oneline` Com base no acima, sugira...
Comando RODA. Resultado já vem no prompt.
🟣 Codex (prosa de fallback)
Antes de começar, rode: - `git branch --show-current` - `git log -1 --oneline` Com base nos resultados, sugira...
Agente RODA os comandos quando lê a skill.
Alternativa: script delegado
Se você precisa de saída idempotente e estruturada, coloque a lógica num script:
# scripts/context.sh #!/bin/bash echo "Branch: $(git branch --show-current)" echo "Commit: $(git log -1 --oneline)" # SKILL.md Antes de começar, rode `./scripts/context.sh` e leia o output.
🦜Polyskill na hora de portar
Quando você importa skill do Claude com backtick-bang, o adapter Codex do polyskill reescreve automaticamente como prosa de fallback. Não é mágica — é simples e funciona. Perde um pouco de elegância em troca de portabilidade.
Conceitos-chave
Codex não tem
"Rode X e analise"
Lógica em sh
Auto na importação
🔌 MCP servers no Codex
Mesma spec MCP. Mesmo server roda. Só a declaração muda — TOML em vez de JSON, dentro do config.toml ou no sidecar openai.yaml da skill (quando MCP é dependência específica).
🔷 Claude (.mcp.json)
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@mcp/github"],
"env": {
"TOKEN": "$GH_TOKEN"
}
}
}
}
🟣 Codex (config.toml)
[mcp_servers.github]
command = "npx"
args = ["-y", "@mcp/github"]
[mcp_servers.github.env]
TOKEN = "${GH_TOKEN}"
Onde declarar — config.toml × sidecar
Conceitos-chave
Server compartilhado
Só sintaxe muda
config.toml × sidecar
Sidecar instala MCP
$ Invocação $skill — não é /skill
Codex usa o cifrão pra invocação explícita de skill, deixando o slash reservado pra comandos built-in. $nome-skill em vez de /nome-skill. Pequeno detalhe que pega no primeiro dia.
🔷 Claude Code
/review ← skill OU slash command /plan ← built-in /output-style x ← built-in
Tudo é slash. Sem separação.
🟣 Codex
$review ← skill /help ← built-in (Codex) /model ← built-in (Codex)
Separação: $ pra skill, / pra built-in.
💡Auto-complete ajuda
Digite $ e o Codex sugere as skills disponíveis. Mesmo esquecendo que é cifrão e não slash, auto-complete corrige rápido.
Conceitos-chave
Sigil de invocação
Reservado
Nome da skill
Lista skills
🎯Resumo do módulo
Próxima trilha:
T4 — Convertendo seu projeto (prompt-template + checklist + 5 armadilhas)