ProAlexUSC/cc-plugin-to-codex

Ponte os plugins do marketplace do Claude Code para o Codex (skills + subagentes).

O que é cc-plugin-to-codex?

Este skill permite que você use qualquer plugin do marketplace do Claude Code (CC) diretamente no Codex, como um agente bridge. Ele sincroniza automaticamente os plugins, convertendo os arquivos Markdown de agentes do CC para o formato TOML do Codex. Todos os artefatos sincronizados recebem um marcador `x-cc-bridge`, permitindo comandos em lote para listar, atualizar ou desinstalar as bridges. Ferramenta essencial para desenvolvedores que querem migrar ou integrar skills e agentes do ecossistema CC no Codex sem retrabalho manual.

Funciona com✓Claude Code✓Codex CLI~Cursor
npx skills add ProAlexUSC/cc-plugin-to-codex

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

cc2codex

CLI que sincroniza plugins do marketplace do CC para o Codex. Cada plugin de origem se torna uma bridge cc-<nome>, o Markdown do agente CC é convertido para TOML do Codex, e cada artefato recebe um marcador x-cc-bridge para que as operações de listar / atualizar / desinstalar possam gerenciá-los em lote.

Instalação

O pacote está publicado no PyPI. Escolha um destes estilos de invocação — os exemplos abaixo assumem que cc2codex está no $PATH:

  1. uvx zero-install (recomendado, sempre a versão mais recente):

    uvx --from cc-plugin-to-codex cc2codex --help
    
  2. uv tool install (persistente):

    uv tool install cc-plugin-to-codex
    cc2codex --help
    
  3. pip simples:

    pip install cc-plugin-to-codex
    cc2codex --help
    

5 comandos

ComandoO que faz
plugin-browseLista somente leitura dos plugins expostos por um marketplace de origem
plugin-syncInstala uma bridge: copia arquivos + converte agentes + atualiza o registro
plugin-listMostra as bridges instaladas (identificadas pelo marcador x-cc-bridge)
plugin-updateRe-sincroniza a partir da origem registrada no marcador
plugin-uninstallRemove uma bridge pelo marcador

Conceitos principais

  • Escopo: global = ~/.codex/ ~/.agents/; project = $PWD/.codex/ $PWD/.agents/. --scope é obrigatório no modo estrito.
  • Origem: uma URL Git (git@host:org/repo.git, https://…/repo.git, ssh://…, git://…, ou git@host:path) ou um caminho local de checkout que contenha .claude-plugin/marketplace.json. Origens Git são clonadas em /tmp e limpas depois. --ref aceita um branch, tag ou SHA de commit.
  • Marcador x-cc-bridge: campo de primeiro nível no plugin.json da bridge, mais um comentário na primeira linha de todo TOML de agente bridge. Arquivos sem o marcador são considerados de autoria do usuário e a ferramenta nunca os sobrescreverá a menos que --force seja passado.
  • Nomeação: o nome da bridge é cc-<plugin-origem>; o nome do arquivo TOML do agente é cc_<plugin_snake>_<agente_snake>.toml (kebab-case → snake_case).

Fluxos típicos

Sincronizar um ou todos os plugins (recomendado para IA)

# Plugins específicos
cc2codex plugin-sync \
  --source https://github.com/sua-org/cc-marketplace.git \
  --plugin ios-dev --plugin base \
  --scope global \
  --non-interactive --yes

# Tudo
cc2codex plugin-sync \
  --source /caminho/para/cc-marketplace \
  --all-plugins --scope global \
  --non-interactive --yes

Re-sincronizar a mesma origem é seguro: agentes que existiam no marcador antigo mas não estão mais presentes na origem são limpos automaticamente.

⚠️ Após plugin-sync o usuário deve instalar a bridge dentro do Codex

O Codex não recarrega a quente ~/.agents/plugins/marketplace.json. Depois que o cc2codex terminar de escrever os arquivos, o usuário precisa reiniciar o Codex (ou iniciar uma nova sessão), executar /plugins, escolher a bridge recém-adicionada no marketplace "CC Bridged Plugins" e instalá-la. Até que essa etapa de instalação seja executada, o Codex não carregará as skills e agentes. Ao explicar uma sincronização bem-sucedida, sempre inclua esta instrução.

Verificar estado

cc2codex plugin-list                       # texto legível
cc2codex plugin-list --scope global --json # legível por máquina

Atualizar

cc2codex plugin-update cc-ios-dev --scope global --non-interactive --yes
cc2codex plugin-update --all --non-interactive --yes

Não é necessário passar --source novamente — a ferramenta lê do marcador.

Desinstalar

cc2codex plugin-uninstall cc-ios-dev --scope global --non-interactive --yes
cc2codex plugin-uninstall --all --scope all --non-interactive --yes

Remove o diretório do plugin + todo TOML de agente associado + a entrada no registro.

⚠️ O Codex tem seu próprio cache; desinstalar cobre apenas metade da história

O cc2codex remove apenas os arquivos que ele escreveu. O Codex tem dois locais de estado extras que o cc2codex não pode tocar:

  • ~/.codex/plugins/cache/cc-bridged-plugins/<bridge>/<versao>/ — o Codex copia as bridges aqui quando o usuário executa /plugins install, e carrega daqui em tempo de execução.
  • ~/.codex/config.toml, seção [plugins."<bridge>@cc-bridged-plugins"] enabled = true — o próprio estado de habilitação do Codex.

Como resultado, uma bridge que foi previamente instalada dentro do Codex ainda será carregada do cache após uma desinstalação do cc2codex. Depois de explicar que a desinstalação foi bem-sucedida, também diga ao usuário para executar /plugins dentro do Codex e desinstalar a mesma bridge lá para que o Codex possa limpar seu próprio cache + configuração.

Ou, manualmente: rm -rf ~/.codex/plugins/cache/cc-bridged-plugins/<bridge> e edite ~/.codex/config.toml para remover a seção [plugins."…"] correspondente.

Regras do modo estrito (importante)

Quando não há TTY ou qualquer um de --yes / --json / --non-interactive é passado, o comando executa no modo estrito. No modo estrito, toda decisão deve ser fornecida explicitamente:

AusenteMensagem de erro
--sourcesource não especificado; passe --source <git-url-ou-caminho>
--plugin ou --all-pluginsnenhum plugin selecionado; passe --plugin <nome> (repetível) ou --all-plugins
--scope`scope não especificado; passe --scope global
uninstall/update sem nome ou --alldeve especificar um nome de bridge ou --all para X (instalados: …)

Ao chamar de uma IA ou script, passe todas as flags explicitamente — não confie em padrões.

Modo interativo

Em um TTY real, omitir uma flag abre um seletor questionary:

  • Tipo de origem: URL Git / Caminho local / Escanear ~/.claude/plugins/marketplaces/
  • Plugins: caixa de seleção múltipla
  • Escopo: global / project
  • Alvo de uninstall / update bridge: caixa de seleção múltipla

Armadilhas comuns

  1. Conflito não-bridge: um diretório de plugin já existe no caminho de destino mas não tem o marcador x-cc-bridge → recusado (protege conteúdo de autoria do usuário). Passe --force para sobrescrever.
  2. Conflito de troca de origem: uma bridge com o mesmo nome foi previamente sincronizada da origem A e agora você está apontando para a origem B → recusado. Execute plugin-uninstall primeiro, ou passe --force.
  3. Nome do plugin vs nome da bridge: --plugin recebe o nome da origem (ex.: ios-dev), não o nome da bridge (cc-ios-dev). O argumento posicional de plugin-uninstall / plugin-update recebe o nome da bridge.
  4. Política de registro: cada entrada de registro é escrita com installation: INSTALLED_BY_DEFAULT + authentication: ON_USE, então o Codex ativa a bridge automaticamente uma vez instalada.
  5. Limpeza de agentes obsoletos é segura: apenas TOMLs que contêm o comentário x-cc-bridge são excluídos; TOMLs de autoria do usuário são deixados intactos.

Referência completa de flags

Flags compartilhadas

FlagSignificado
--source <url-ou-caminho>URL Git (git@host:org/repo.git, https://…/repo.git) ou caminho local (diretório contendo .claude-plugin/marketplace.json). Omita para selecionar interativamente.
`--ref <branchtag
--scope {global,project}Escopo de destino. global → ~/.codex/ ~/.agents/; project → $PWD/.codex/ $PWD/.agents/. Obrigatório no modo estrito para plugin-sync.
--scope {global,project,all}Filtro de escopo para plugin-list, plugin-update, plugin-uninstall. Padrão all.
--plugin <nome>Repetível. Recebe o nome do plugin do lado da origem (sem prefixo cc-). Mutuamente exclusivo com --all-plugins.
--all-pluginsSincroniza todos os plugins expostos pela origem.
--allAplica plugin-update / plugin-uninstall a todas as bridges no escopo de destino.
--yesPula prompts de confirmação (implica modo estrito).
--non-interactiveForça modo estrito; ativado automaticamente quando stdin não é um TTY.
--forceIgnora proteção de conflito (sobrescrita de não-bridge, origem diferente).
--jsonEmite JSON legível por máquina na stdout (implica modo estrito).

plugin-browse

Listagem somente leitura de plugins em um marketplace de origem. Não escreve nada.

cc2codex plugin-browse --source <url-ou-caminho> [--ref <ref>] [--json]

Não interativo: --source é obrigatório.

plugin-sync

Comando principal de instalação. Pipeline:

  1. Resolver a origem (clonar Git em /tmp, ou ler o caminho local).
  2. Ler <origem>/.claude-plugin/marketplace.json para listar plugins disponíveis.
  3. Filtrar com --plugin / --all-plugins.
  4. Para cada plugin selecionado:
    • Pré-converter todos os agents/*.md (falhar rapidamente).
    • Verificar conflitos de TOML de agente (autoria do usuário → recusar a menos que --force).
    • Preparar um diretório irmão e copiar (lista negra exclui .claude-plugin/, .codex-plugin/, hooks/, commands/, agents/, VCS/ruído de build).
    • Escrever .codex-plugin/plugin.json incluindo o marcador x-cc-bridge e a lista final de agentes.
    • Renomear atomicamente (POSIX) o diretório preparado sobre a bridge antiga.
    • Escrever TOMLs de agente (comentário # x-cc-bridge: {…} na linha 1).
    • Remover agentes obsoletos (no marcador antigo mas não na nova lista).
    • Inserir ou atualizar a entrada no marketplace.json (policy.installation = INSTALLED_BY_DEFAULT).
cc2codex plugin-sync \
  --source <url-ou-caminho> [--ref <ref>] \
  --scope {global|project} \
  {--plugin <nome> [--plugin <nome>] … | --all-plugins} \
  [--force] [--yes] [--non-interactive] [--json]

Não interativo: --source, --scope e --plugin|--all-plugins são todos obrigatórios.

plugin-list

Escaneia todo diretório de plugin no escopo de destino e lista aqueles que contêm um marcador x-cc-bridge.

cc2codex plugin-list [--scope {global|project|all}] [--json]

Modo texto imprime caminhos de pluginsDir / agentsDir / registry para cada escopo seguido pelo inventário de bridges com nomes de agentes. Modo JSON agrupa os mesmos dados por escopo.

plugin-update

Usa o x-cc-bridge.source + .ref da bridge para re-resolver a origem e executar o pipeline de sincronização. Argumentos de origem NÃO são necessários novamente.

cc2codex plugin-update [cc-<nome> | --all] \
  [--scope {global|project|all}] \
  [--force] [--yes] [--non-interactive] [--json]
  • O argumento posicional é o nome da bridge (com prefixo cc-).
  • --all atualiza todas as bridges no escopo de destino.
  • No modo estrito, um nome ausente / --all aciona um erro que lista as bridges instaladas.

plugin-uninstall

Limpeza orientada por x-cc-bridge.agents. Apenas arquivos com o marcador são removidos; plugins e agentes de autoria do usuário estão sempre seguros.

cc2codex plugin-uninstall [cc-<nome> | --all] \
  [--scope {global|project|all}] \
  [--yes] [--non-interactive] [--json]

Ordem de exclusão:

  1. Cada TOML de agente listado em x-cc-bridge.agents.
  2. O próprio diretório scope.plugins_dir/cc-<nome>/.
  3. A entrada em scope.registry (o array plugins[] de marketplace.json).

O arquivo marketplace.json em si nunca é removido, mesmo quando o array fica vazio (plugins: []).

Esquemas JSON

plugin-browse --json

{
  "marketplace": {
    "name": "<string>",
    "source": "<string>",
    "sourceKind": "git|local",
    "ref": "<string or null>",
    "commit": "<string>"
  },
  "plugins": [
    {
      "name": "<string>",
      "version": "<string>",
      "description": "<string>",
      "skillCount": 0,
      "agentCount": 0,
      "hasCodexManifest": true
    }
  ]
}

plugin-sync --json

{
  "scope": "global|project",
  "synced": [
    {
      "bridgeName": "cc-<nome>",
      "bridgeDir": "<caminho absoluto>",
      "agents": ["cc_<plugin>_<agente>", "..."]
    }
  ]
}

plugin-list --json

{
  "scopes": {
    "global": {
      "pluginsDir": "<caminho>",
      "agentsDir": "<caminho>",
      "registry": "<caminho>",
      "bridges": [
        {
          "name": "cc-<nome>",
          "version": "<string>",
          "sourcePlugin": "<nome origem>",
          "source": "<url-ou-caminho>",
          "sourceKind": "git|local",
          "ref": "<string or null>",
          "commit": "<sha or 'local'>",
          "marketplace": "<nome do marketplace origem>",
          "syncedAt": "<ISO-8601 UTC>",
          "agents": ["cc_<plugin>_<agente>", "..."]
        }
      ]
    },
    "project": { "...": "mesma estrutura" }
  }
}

plugin-update --json

{
  "updated": [
    {"bridgeName": "cc-<nome>", "commit": "<sha>", "scope": "global|project"}
  ]
}

plugin-uninstall --json

{
  "removed": [
    {"bridge": "cc-<nome>", "agents": ["cc_<plugin>_<agente>", "..."], "scope": "global|project"}
  ]
}

Códigos de saída

CódigoSignificado
0Sucesso
1Erro em tempo de execução (bridge não encontrada, conflito não resolvido, SyncConflictError, …)
2Argumentos ausentes / inválidos (modo estrito, nome de plugin desconhecido, …)

Formato do marcador x-cc-bridge

Escrito no primeiro nível de <scope.plugins_dir>/cc-<nome>/.codex-plugin/plugin.json:

{
  "x-cc-bridge": {
    "sourcePlugin": "<nome da origem sem prefixo cc->",
    "source": "<url ou caminho absoluto>",
    "sourceKind": "git|local",
    "ref": "<branch/tag/sha or null>",
    "commit": "<sha or 'local'>",
    "marketplace": "<nome do marketplace.json origem>",
    "syncedAt": "<ISO-8601 UTC>",
    "tool": "cc-plugin-to-codex/<versao>",
    "agents": ["cc_<plugin>_<agente>", "..."]
  }
}

Comentário na primeira linha de cada TOML de agente bridge:

# x-cc-bridge: {"sourcePlugin":"<nome>","sourceAgent":"<nome-original>","bridgePlugin":"cc-<nome>","syncedAt":"..."}
name = "cc_<plugin>_<agente>"
description = "..."
developer_instructions = """..."""

Regras de detecção:

  • plugin.json é uma bridge se e somente se tiver um dicionário x-cc-bridge no primeiro nível.
  • Um TOML de agente é uma bridge se e somente se sua primeira linha corresponde à regex ^# x-cc-bridge: (\{.*\})$, o payload JSON analisa e as quatro chaves obrigatórias estão presentes.

Qualquer coisa sem correspondência é tratada como de autoria do usuário; a ferramenta não mexe. --force é a única maneira de sobrescrever.

Habilidades Relacionadas