1

Como descobrir o tamanho da janela de contexto do Claude Code quando nada te conta

Mantenho uma extensão de VSCode (open-source) que lê os transcripts do Claude Code e mostra o uso da sessão num painel — tokens, % de contexto, cache. Pra exibir "você usou 45% do contexto" eu preciso de duas coisas: quantos tokens estão na janela agora (fácil) e o tamanho da janela (200k ou 1M). Foi aí que travei — e virou uma caça que mexe com os internals do Claude Code. Compartilho porque talvez te poupe tempo.

O claude-opus-4-8 suporta 1M de contexto. Mas o id não diz isso, e descobri que esse "1M vs 200k" não está em nenhum lugar óbvio.

1. O transcript não tem

Cada turno é gravado em ~/.claude/projects/<cwd>/<sessionId>.jsonl. O message.usage é rico:

"usage": {
  "input_tokens": 2,
  "cache_creation_input_tokens": 2268,
  "cache_read_input_tokens": 443072,
  "output_tokens": 3245,
  "service_tier": "standard"
}

Somando input + cache_read + cache_creation eu sei o tamanho atual do contexto (~445k aqui). Mas o limite não está. Vasculhei message.diagnostics (só cache_miss_reason), stop_details, campos de topo (version, cwd, gitBranch). Um grep por context_window, max_tokens, betas, 1m em todos os .jsonl: zero. O beta context-1m viaja só no header HTTP — que não é gravado.

2. Os hooks não têm

O Claude Code dispara hooks com um JSON no stdin. Pela doc oficial, só o SessionStart recebe um campo model — e é o mesmo id cru, sem janela nem beta. Nenhum hook recebe o context window. O hook só me daria o que eu já tinha.

3. Tem um campo… que é sempre 0

Achei ~/.claude/stats-cache.json com modelUsage.<model>.contextWindow. Animei. É sempre 0 — campo existe no schema, nunca preenchido.

4. O statusline TEM — mas sai caro

A única fonte de verdade local é o JSON que o Claude Code passa a um script de statusline:

context_window.context_window_size → "200000 by default, or 1000000 for models with extended context"

Exato. Mas pra capturar isso minha extensão teria que registrar um statusline no settings do usuário, o que (a) adiciona uma barra na TUI que ele não pediu e (b) conflita com um statusline que ele já tenha (só pode existir um). Caro demais pra um indicador.

A solução: heurística

Sem fonte de verdade barata, combinei dois sinais, sempre elevando, nunca rebaixando:

  • Família: opus/sonnet geração 4+ suportam 1M → assume 1M. (com regex cuidadoso pra não casar o id antigo claude-3-5-sonnet-20241022)
  • Evidência: se o contexto observado já passou de 200k, a janela é ≥1M por definição — cobre qualquer modelo futuro.

O erro residual (rodar opus/sonnet 4+ sem o beta 1M → mostro % subestimado) é o menos grave, e o autocompact do Claude Code ainda protege.

Moral

Pra quem integra "de fora" com o Claude Code: o usage por turno é ótimo, mas o tamanho da janela é um ponto cego — não está no transcript nem nos hooks, só no statusline (e a um custo). Se alguém conhece uma fonte melhor, comenta — tô curioso de verdade.

Isso foi parar na minha extensão (Claude Todos, MIT, lê os transcripts e mostra o painel de uso), mas o que eu queria dividir aqui é a caça — "o dado existe, só não onde você esperava" é das partes mais chatas (e divertidas) de integrar com ferramenta dos outros.

Repo: https://github.com/carlosdealmeida/claude-todos-vscode

Carregando publicação patrocinada...