Pitch: O que aprendi lendo os logs não documentados do Claude Code, Codex e Mistral Vibe
Quem roda vários agentes de programação ao mesmo tempo ganha um trabalho extra que ninguém pediu: ficar de olho neles. Três sessões do Claude Code, uma delas abre quatro subagentes, um Codex rodando uma migração em outro terminal… e você passa a tarde alternando abas para responder sempre às mesmas perguntas: esse ainda está trabalhando? Travou num comando? Está esperando por mim?
A resposta está no disco. O Claude Code, o Codex e o Mistral Vibe gravam tudo o que fazem em arquivos locais, em tempo real, e nenhum deles documenta o formato. Passei as últimas semanas lendo esses arquivos para construir uma ferramenta, e aqui vai o que aprendi, caso você queira fazer algo parecido.
Claude Code: um JSONL por sessão
Cada sessão fica em ~/.claude/projects/<pasta>/<id-da-sessão>.jsonl. A pasta é o caminho do projeto com todo caractere que não é letra nem dígito trocado por - (/Users/eu/loja-api vira -Users-eu-loja-api). Cada linha é um registro JSON com um type: user e assistant carregam a conversa, e uma mensagem do assistente traz blocos text, thinking e tool_use. O resultado de cada ferramenta volta num registro user seguinte, como um bloco tool_result com o mesmo tool_use_id.
As armadilhas:
- O uso de tokens vem repetido. A mesma mensagem do assistente é gravada uma vez por bloco de conteúdo, sempre com o mesmo
usage. Conte uma vez pormessage.id, senão uma mensagem com cinco blocos custa cinco vezes mais. - Silêncio não é fim. O fim de um turno é uma marca explícita,
stop_reason: "end_turn". Até ela chegar, o agente ainda está trabalhando, mesmo depois de um minuto sem escrever nada. - Subagentes têm arquivos próprios, em
<id-da-sessão>/subagents/*.jsonl. A primeira mensagem de usuário de um subagente é a ordem que ele recebeu. - "Precisa de você" não está no transcript. Quando um menu de permissão está aberto, a chamada pendente muitas vezes ainda não foi gravada. O estado confiável fica em
~/.claude/sessions/<pid>.json(status: "waiting"). Mas cuidado:waitingFor: "dialog open"é só um diálogo de slash command aberto, não uma pergunta para você.
Codex: um arquivo "rollout" por thread
O Codex (app e CLI) grava em ~/.codex/sessions/AAAA/MM/DD/rollout-<hora>-<id>.jsonl. A primeira linha é um session_meta com id, cwd, source e, para uma thread filha, parent_thread_id. Use esse campo para ligar filhos e pais, nunca nomes de arquivo ou horários.
Surpresa: na minha máquina, 34 de 57 rollouts eram {"subagent":{"other":"guardian"}}, as revisões automáticas curtas que o Codex roda antes de alguns comandos. Se você mostrar tudo como sessão, a lista se afoga.
Mistral Vibe: dois formatos ao mesmo tempo
O Vibe guarda as sessões em ~/.vibe/logs/session e, desde a versão 2.26, tem dois motores com dois formatos diferentes: o antigo, um arquivo por sessão, e o novo, em logs/session/unified/<id>/, com um snapshot (CURRENT), páginas de histórico em chunks/ e um journal que vai sendo acrescentado. Um leitor precisa entender os dois, porque as duas coisas convivem na mesma máquina.
O que eu fiz com isso
Juntei tudo num app open source, o Agent Standup, que transforma essas sessões numa chamada de equipe ao vivo: o agente principal dá as ordens, os subagentes entram na chamada quando recebem uma tarefa e saem quando terminam, e quem está trabalhando compartilha a tela com o comando e a saída real, ou o diff que está aplicando.

Algumas decisões técnicas, para quem gosta:
- Zero dependências em runtime. Um servidor Node só com a biblioteca padrão, que lê os JSONL de forma incremental (guarda o offset de cada arquivo e só lê o que foi acrescentado).
- Não gasta tokens. Nenhum modelo é chamado para "assistir" os agentes: é só leitura de arquivo. Roda local e não envia nada por padrão.
- Vozes locais. As falas saem de um modelo de voz pequeno (Kokoro) que roda na sua máquina, com a boca sincronizada pelo volume real do áudio.
- Formatos que mudam sem aviso. Todo leitor é defensivo: campo ausente não quebra nada, e uma sessão ilegível do Codex ou do Vibe derruba só aquela sessão, nunca a lista inteira.
Para testar sem instalar nada (Node 18+):
npx @double_geste/agent-standup@latest --open
Sem sessão ainda? ⚙ → Fonte → Demo mostra uma equipe fictícia. Também existe como extensão do VS Code (e Cursor/Windsurf pela Open VSX) e app para macOS. Licença MIT, interface em português do Brasil: https://agent-standup.com/pt-br/
Fiquei curioso: quantas sessões de agente vocês rodam ao mesmo tempo, e como sabem qual delas está esperando por vocês?