Isolar contas com CODEX_HOME, alternar profiles e fazer duas instâncias conversarem nativamente — sem tocar na conta principal
O mesmo binário. O mesmo Mac. Duas contas completamente diferentes.
No primeiro terminal, codex abre autenticado na conta A — a sua conta principal, com os repositórios confiados, os skills, as sessões e a organização de sempre. No segundo terminal, codex abre autenticado na conta B — uma conta separada, com histórico, contexto e permissões próprias. Nenhum toca o estado do outro.
Parece mágica. Não é. É um detalhe de configuração que quase ninguém documenta direito: o Codex não é preso a um único diretório de configuração. Ele resolve tudo — login, config, sessões, skills, histórico — a partir de uma variável de ambiente chamada CODEX_HOME.
Se você entende isso, abre um leque de possibilidades que vai muito além de "rodar dois terminais":
Este artigo é um tutorial completo, baseado numa configuração real que já roda em produção num Mac: a conta A em ~/.codex e a conta B em ~/.codex-lemon-dev, acessadas por wrappers chamados codex-lemon-dev-cli e codex-lemon-dev.
A tese central é simples:
Uma instância do Codex é definida pelo seu CODEX_HOME. Controle o CODEX_HOME e você controla quantos mundos isolados quiser rodar ao mesmo tempo.
Antes de configurar qualquer coisa, vale entender o que você está configurando. Muita gente imagina o Codex como "um app" ou "um CLI". Na prática, o que existe é um binário (codex) que lê, a cada execução, um diretório de estado.
Por padrão, esse diretório é ~/.codex. É lá que moram:
~/.codex/
├── auth.json # login (tokens, account_id, auth_mode)
├── config.toml # modelo, profiles, projetos, MCP servers, features
├── sessions/ # sessões interativas
├── skills/ # skills carregados sob demanda
├── plugins/ # plugins e marketplaces
├── thread_history_1.sqlite # histórico de conversas
├── logs_2.sqlite # logs
├── state_5.sqlite # estado do daemon/agentes
└── ...
Tudo que faz de uma instância "aquela" instância — a conta logada, o modelo, os projetos confiáveis, as conversas passadas — está dentro desse diretório. Não existe um estado global mágico em outro lugar.
Isso tem uma consequência prática enorme:
Se você apontar o CODEX_HOME para outro diretório, você tem uma instância completamente nova. Mesmo binário. Estado zero. Conta própria.
A documentação oficial confirma isso na página de environment variables: o CODEX_HOME sobrepõe o diretório de configuração padrão. O binário não se importa se esse diretório é ~/.codex, ~/.codex-lemon-dev ou qualquer outro caminho que você criar.
Antes de sujar as mãos, deixe o porquê claro. Rodar duas instâncias não é vaidade de power-user. É a resposta a problemas reais.
Quem trabalha com IA acaba com mais de uma conta OpenAI: uma pessoal, uma da empresa, talvez uma de teste. Fazer codex logout e codex login toda vez é desgastante e arriscado — você perde o contexto, esquece em qual conta está e, pior, mistura histórico.
Com CODEX_HOME isolado, cada conta vive no seu próprio diretório. Você nunca mais faz logout para trocar de conta. Só muda o wrapper que chama.
Dois agentes trabalhando ao mesmo tempo é a base de muita automação: um revisa enquanto o outro implementa, um pesquisa docs enquanto o outro roda testes. Com uma instância só, você fica preso a uma conversa por vez (ou a worktrees, que resolvem outra coisa).
Com duas instâncias, você tem dois cérebros independentes rodando de verdade em paralelo.
Um novo skill, um novo provider via --oss, uma mudança agressiva de sandbox_mode — nada disso deveria arriscar a instância que você usa todo dia. Uma instância descartável é a forma mais barata de experimentar sem medo.
Você pode ter uma instância "fundo total" (sandbox danger-full-access) e outra "somente leitura" (sandbox read-only) apontando para o mesmo repositório. Escolhe a instância conforme o risco da tarefa, sem reconfigurar nada.
~/.codex)A conta A normalmente já existe. É a que o Codex usa por padrão quando você roda codex sem nenhuma variável especial.
Para conferir qual conta está ativa:
codex login status
Se você ainda não fez login, o Codex oferece três caminhos oficiais:
# 1. Login via ChatGPT (abre o browser, fluxo OAuth)
codex login
# 2. Login via device code (útil em headless / CI)
codex login --device-auth
# 3. Login via API key (lê a chave do stdin)
printenv OPENAI_API_KEY | codex login --with-api-key
O resultado fica gravado em ~/.codex/auth.json. Você pode abrir esse arquivo e ver o campo auth_mode (chatgpt para login de assinatura, ou apikey) e o account_id — é assim que você confirma qual conta está de fato logada.
A página oficial de authentication detalha os métodos de sign-in. Vale a leitura se você trabalha com orgs múltiplas ou workload identity.
~/.codex-lemon-dev)Aqui está o coração do tutorial. Para criar uma segunda instância com uma segunda conta, você não instala nada de novo. Você só cria um diretório limpo e faz login lá dentro.
# Cria o novo CODEX_HOME
mkdir -p ~/.codex-lemon-dev
# Faz login da conta B DENTRO desse diretório
CODEX_HOME=~/.codex-lemon-dev codex login
A partir desse momento, ~/.codex-lemon-dev é um mundo completo: auth.json próprio, config.toml próprio, sessions/ próprias, skills/ próprios.
Confirme que deu certo comparando os dois auth.json:
grep account_id ~/.codex/auth.json
grep account_id ~/.codex-lemon-dev/auth.json
Se os account_id forem diferentes, você tem duas contas rodando lado a lado.
OPENAI_API_KEYExiste um erro silencioso que faz a conta B autenticar na conta errada — ou, pior, parecer logada sem estar.
O Codex resolve a autenticação nesta ordem de prioridade:
OPENAI_API_KEY, CODEX_ACCESS_TOKEN);CODEX_HOME (auth.json).Se o seu shell exporta OPENAI_API_KEY globalmente (muito comum em .zshrc ou .bashrc), qualquer codex que você rodar vai ignorar o login do auth.json e usar a API key. Isso significa que a sua conta B, logada via ChatGPT, na prática autentica como a API key da conta A — o isolamento vai pro espaço sem nenhum aviso.
A correção é uma linha no wrapper:
unset OPENAI_API_KEY
É exatamente isso que o wrapper codex-lemon-dev-cli faz (você vai vê-lo completo daqui a pouco). Essa linha é a diferença entre "duas contas de verdade" e "duas janelas que no fundo são a mesma chave".
Rodar CODEX_HOME=... codex toda vez funciona, mas é frágil. Você esquece o prefixo, o shell antigo vaza a variável, e o isolamento desanda.
A solução é um wrapper — um script mínimo que encapsula o CODEX_HOME e o unset da API key. Dois wrappers cobrem os dois produtos: CLI e App.
codex-lemon-dev-cliCrie ~/.local/bin/codex-lemon-dev-cli:
#!/bin/zsh
# Conta B / Lemon Dev — CLI
# Isola a Conta B em ~/.codex-lemon-dev sem tocar em ~/.codex (Conta A).
set -e
export CODEX_HOME="$HOME/.codex-lemon-dev"
mkdir -p "$CODEX_HOME"
# O .zshrc exporta OPENAI_API_KEY globalmente, o que faria a Conta B autenticar
# por API key em vez do login ChatGPT proprio. Removido apenas neste processo.
unset OPENAI_API_KEY
exec codex "$@"
Torne executável:
chmod +x ~/.local/bin/codex-lemon-dev-cli
Agora, a troca de conta é explícita e à prova de erro:
codex # Conta A (padrão, ~/.codex)
codex-lemon-dev-cli # Conta B (~/.codex-lemon-dev)
codex-lemon-devO CLI é simples. O Codex App tem uma pegadinha extra: ele é um app Chromium e, por padrão, é single-instance. Se você tentar abrir uma segunda cópia, o macOS simplesmente encaminha para a primeira instância já aberta — e o CODEX_HOME dela prevalece. Ou seja, sem cuidado, a "conta B" do App abre, na real, a conta A.
A correção é dar à segunda instância um --user-data-dir próprio. Cada user-data-dir é um perfil Chromium independente, que roda como processo separado e coexiste com o outro.
#!/bin/zsh
# Conta B / Lemon Dev — Desktop App
# Abre o Codex Desktop com CODEX_HOME apontando para a Conta B.
set -e
export CODEX_HOME="$HOME/.codex-lemon-dev"
mkdir -p "$CODEX_HOME"
unset OPENAI_API_KEY
APP="/Applications/ChatGPT.app"
BIN="$APP/Contents/MacOS/ChatGPT"
if [[ ! -x "$BIN" ]]; then
print -u2 "codex-lemon-dev: $APP nao encontrado."
exec codex app "$@"
fi
# O app e Chromium e e single-instance por user-data-dir. Com um perfil proprio,
# a Conta B abre como processo separado e coexiste com a Conta A.
PROFILE="$CODEX_HOME/chromium-profile"
mkdir -p "$PROFILE"
# Executa o binario direto: `open` nao propaga variaveis de ambiente.
exec "$BIN" --user-data-dir="$PROFILE" "$@"
Dois detalhes que fazem toda a diferença:
exec "$BIN" em vez de open — o open do macOS não propaga variáveis de ambiente para o processo filho. Se você usasse open -a ChatGPT, o CODEX_HOME se perderia. Executar o binário direto garante que o CODEX_HOME chegue intacto.--user-data-dir dedicado — é o que quebra o single-instance do Chromium e permite as duas contas coexistirem.A documentação oficial de desktop app e de config cobre a base do app e do arquivo de configuração, respectivamente.
Até aqui, o mecanismo foi "um CODEX_HOME por conta". Mas existe um segundo eixo de configuração, mais fino: os profiles.
Um profile é um conjunto de overrides dentro de um config.toml. Você define [profiles.nome] e seleciona com -p ou --profile. Exemplo real:
# ~/.codex/config.toml
[profiles.full_auto]
approval_policy = "on-request"
sandbox_mode = "workspace-write"
[profiles.readonly_quiet]
approval_policy = "never"
sandbox_mode = "read-only"
[profiles.deep_research]
model = "gpt-5"
model_reasoning_effort = "high"
Uso:
codex -p readonly_quiet # só leitura, nunca pede aprovação
codex -p deep_research # modelo maior, raciocínio alto
codex exec -p full_auto "..." # não-interativo com profile
Você também pode fazer override pontual com -c:
codex -c 'model="gpt-5.6-luna"' -c 'sandbox_mode="workspace-write"'
A referência completa de chaves está na página de config reference. E a página de permissions explica os profiles de permissão beta (filesystem e rede).
A confusão mais comum é achar que CODEX_HOME e profile fazem a mesma coisa. Não fazem:
| Eixo | O que isola | Mecanismo |
|---|---|---|
CODEX_HOME | conta, sessões, histórico, skills, plugins | diretório de estado diferente |
profile | modelo, permissões, política de aprovação | overrides no mesmo config.toml |
Você usa CODEX_HOME para quem está falando (a conta), e profile para como aquela conta se comporta (modelo, sandbox, aprovação). Os dois se combinam livremente:
CODEX_HOME=~/.codex-lemon-dev codex -p deep_research
Conta B, perfil de pesquisa profunda. Sem conflito.
Agora a parte divertida. Você tem dois wrappers (ou um wrapper + o binário puro) e pode abrir duas sessões ao mesmo tempo.
O jeito mais direto é o tmux (ou duas janelas de terminal):
# painel 1 — Conta A
codex
# painel 2 — Conta B
codex-lemon-dev-cli
Cada painel é uma sessão independente: histórico próprio, estado próprio, conta própria. Podem estar no mesmo repositório sem conflito, porque o estado não fica no repositório — fica no CODEX_HOME.
Para trabalho não-interativo (automação, CI, scripts), o codex exec é a ferramenta certa:
# conta A executa uma tarefa e devolve o resultado no stdout
codex exec "liste os TODOs do repositório"
# conta B executa uma tarefa diferente em paralelo
codex-lemon-dev-cli exec "rode os testes e resuma as falhas"
# resume/fork de uma sessão existente
codex exec resume --last
codex exec fork <session-id>
O exec aceita stdin também — o que abre a porta para o próximo tópico:
cat arquivo.txt | codex exec "resuma este arquivo"
É aqui que o tutorial fica de verdade interessante. O Codex tem recursos nativos para uma instância falar com a outra. Você não instala nada — são subcomandos que já vêm no binário.
codex exec encadeado: uma passa o bastão para a outraO codex exec lê do stdin e escreve no stdout. Isso significa que você pode encadear instâncias como se fossem funções de um pipe:
# Conta A pesquisa; a saída vira entrada da Conta B, que implementa
codex exec "liste os 3 bugs mais críticos do projeto" \
| codex-lemon-dev-cli exec "implemente correções para os bugs listados"
A conta A faz o trabalho de análise, a conta B recebe o resultado e age. Dois cérebros, uma tarefa, zero integração customizada.
Você pode inclusive pedir a uma instância para comandar a outra:
codex exec "gere um plano de migração em markdown" > plano.md
codex-lemon-dev-cli exec "execute o plano em plano.md, passo a passo" < plano.md
codex queue: injetar mensagem numa sessão que já está rodandoSe a instância B já está em uma sessão interativa (num terminal aberto), você pode enfileirar uma mensagem naquela sessão sem precisar digitar nela:
codex queue --thread <session-id-ou-nome> --message "pode revisar o PR #42 agora?"
A sessão B recebe a mensagem como se você tivesse digitado ali. É a forma mais barata de "chamar a atenção" de outra instância rodando.
codex agents e app-server: o daemon compartilhadoO Codex tem um daemon local (app-server) que registra todas as sessões de agentes. O subcomando agents lista essas sessões:
codex agents
Isso é a espinha dorsal de uma arquitetura multi-instância: um daemon, várias sessões, todas endereçáveis. Os subcomandos app-server daemon, app-server proxy e remote-control dão controle programático sobre esse daemon (a documentação oficial de app-server detalha o protocolo para embutir o Codex no seu produto).
codex mcp-server: uma instância vira ferramenta da outraPara quem quer o grau máximo de integração, o Codex pode se expor como um servidor MCP em stdio:
codex mcp-server
Aí você registra a instância como um MCP server na outra — a conta A passa a enxergar a conta B como uma ferramenta que ela pode invocar. É o caminho de "agente chamando agente" por protocolo aberto.
Nota: a documentação marca o
mcp-serverstandalone como deprecated, apontando para oapp-server(ou o plugin do Codex para Claude Code) como sucessor. Para novos projetos, prefira o app-server. Mas o comando ainda funciona e serve bem como experimento.
Juntando tudo, dá para montar um mini-orquestrador só com o que é nativo:
#!/bin/zsh
# Conta A (estrategista) planeja; Conta B (executor) implementa.
set -e
# 1. Conta A produz o plano
codex exec "analise o repo e gere um plano de refactor em markdown" > /tmp/plano.md
# 2. Conta B executa o plano
codex-lemon-dev-cli exec "execute o plano a seguir" < /tmp/plano.md
# 3. Conta A revisa o diff produzido pela B
git diff | codex exec "revise este diff e aponte riscos"
Três passos, duas contas, nenhuma dependência externa. A conta A planeja e revisa; a conta B executa. Cada uma com seu contexto e sua política de aprovação.
Configuração de múltiplas instâncias falha de forma bem previsível. Aqui estão os erros que custam caro.
OPENAI_API_KEY vazando entre instânciasJá mencionei, mas repito porque é o erro número um. Se a API key global está no shell, todo codex a usa, ignorando o auth.json do CODEX_HOME. Sintoma: "logei na conta B mas ela ainda usa a cota/config da conta A".
Fix: unset OPENAI_API_KEY no wrapper — e confirme com codex login status qual conta está ativa.
Sintoma: você roda codex-lemon-dev e a janela que abre é a conta A. Causa: single-instance do Chromium.
Fix: --user-data-dir exclusivo por instância, como no wrapper acima.
CODEX_HOME e profile são a mesma coisaSão eixos ortogonais. CODEX_HOME troca a identidade; profile troca o comportamento. Usar um quando precisa do outro gera isolamento incompleto ou overrides confusos.
CODEX_HOME tem seus próprios skills e pluginsUm skill instalado na conta A não existe na conta B. Se você depende de um skill específico, precisa instalá-lo (ou symlinkar) no CODEX_HOME da segunda instância também. Isso vale para marketplaces, MCP servers e memórias.
O sandbox_mode (workspace-write, read-only, danger-full-access) é configurado por instância/profile. Se a conta B rodar com danger-full-access e você não quiser isso, ajuste o config.toml do ~/.codex-lemon-dev, não do ~/.codex. A página de sandboxing cobre os modos.
Antes de usar no dia a dia, passe por este filtro:
codex login status mostra a conta A correta?CODEX_HOME=~/.codex-lemon-dev codex login status mostra a conta B?account_id são diferentes?unset OPENAI_API_KEY?--user-data-dir exclusivo?config.toml certo?codex -p <profile> seleciona o profile esperado?codex exec encadeado entre as duas funciona?Se todos os checks passarem, você tem um setup de multi-instância sólido.
O mercado gosta de falar de modelos e benchmarks. Mas, no uso diário, muito do poder de uma ferramenta como o Codex vem de um detalhe menos glamouroso: onde ele guarda o seu estado, e como você controla isso.
CODEX_HOME é o botão que quase ninguém aperta. Com ele, o Codex deixa de ser "um agente na sua máquina" e vira "quantos agentes isolados você quiser, na mesma máquina". Duas contas sem logout. Dois cérebros em paralelo. Instâncias que conversam via exec, queue, agents e app-server — tudo nativo.
Se eu tivesse que resumir o argumento deste artigo em uma frase, seria esta:
Um binário, muitos mundos. O que separa uma conta da outra não é um app novo — é um CODEX_HOME bem definido.
E, em automação, saber onde termina uma instância e começa a outra é o que separa um setup que funciona de um que te cobra caro depois.
Produtos gratuitos e pagos para transformar ideias em uma base que você consegue executar.
11 produtos disponíveisContinue explorando tópicos similares

OpenAI and Anthropic are no longer competing only on chatbot quality. In 2026, they are fighting over the operating layer where companies build, analyze, audit, sell, research, and decide.

Muita gente tenta resolver tudo com um prompt melhor, quando o problema real é a escolha errada da skill. Este guia mostra o que são skills no Claude Code, por que elas importam tanto e como escolher a skill correta para obter resultados mais consistentes, seguros e úteis.

Nos últimos meses, os agentes de Inteligência Artificial deixaram de ser apenas copilotos de código e passaram a agir como verdadeiros engenheiros virtuais. Ferramentas como Claude Code, Codex CLI e Gemini CLI estão mudando completamente a forma como desenvolvedores escrevem, testam e otimizam código.
Checklist de 47 pontos para encontrar bugs, riscos de segurança e problemas de performance antes do lançamento.
Templates testados em produção, usados por desenvolvedores. Economize semanas de setup no seu próximo projeto.
