token-trace-manager
v0.7.10
Published
Proxy local universal de rastreio de tokens de LLM para TUIs de código (Claude Code, Codex, OpenCode, Gemini CLI, Kilo...), com labels por tarefa, dashboard local e auto-link que preserva redirects prévios (z.ai/GLM/...).
Maintainers
Readme
token-trace-manager (ttm)
Proxy local universal de rastreio de tokens e custo para TUIs de código — Claude Code, Codex, OpenCode, Gemini CLI, Kilo Code, Goose, Crush, Aider, Cline, Roo Code, Droid, Copilot CLI e qualquer ferramenta que permita trocar a base URL do provedor.
Um único daemon local intercepta as chamadas de API de todas as suas ferramentas, extrai o uso de tokens (streaming ou não), atribui a um label/ticket (ex: PROJ-123) e mostra tudo num dashboard local. Um servidor MCP embutido deixa o próprio agente consultar e controlar o rastreio de dentro de qualquer TUI compatível com MCP.
Regras de ouro
- Escuta só em
127.0.0.1(porta padrão 25519, configurável) — nunca exposto na rede. - Nunca toca nas chaves: os headers de autenticação (
x-api-key,Authorization) são repassados intactos ao provedor real e jamais gravados — em nenhum arquivo, nem nos payloads. - Conteúdo é seu, e fica local: por padrão, request/response de cada chamada são guardados em JSONs locais (
payloads/) para inspeção mensagem a mensagem na página Traces — seguindo a mesma retenção (24h) e com botão de desligar na/configpara quem não quiser conteúdo em disco.
Arquitetura
Claude Code ──┐ ┌──> api.anthropic.com
Codex ────────┤ proxyURL ├──> api.openai.com
OpenCode ─────┼─> http://127.0.0.1:25519 ┼──> generativelanguage.googleapis.com
Gemini CLI ───┤ /{target}/{TICKET?}/… ├──> openrouter.ai/api
│ /{target}/-/{slug}/… │
Kilo, etc ────┘ │ └──> (targets customizados)
│ tee (só metadados de usage)
v
SQLite local ──> dashboard http://127.0.0.1:25519/dashboard
^
servidor MCP (ttm_status, ttm_activate, ttm_usage_summary, ...)- targetUrl — a URL real do provedor que o TUI chamaria sem proxy (já vem preenchida para
anthropic,openai,geminieopenrouter; adicione outras no config). - proxyURL —
http://127.0.0.1:25519. O primeiro segmento do path escolhe o target; um segundo segmento opcional no formatoTICKET-123vira o label daquela chamada. Para labels descritivos que não são ticket, use a forma explícita/{target}/-/{slug}/..., sem ambiguidade com o path real do provedor.
Instalação
Pré-requisito: Node ≥ 22.5. Sem dependências, sem build — é Node puro.
npm install -g token-trace-manager # 1. instala o bin `ttm`
ttm start # 2. sobe o daemon (porta 25519, só 127.0.0.1)
ttm link claude-code # 3. insere o ttm no meio do seu TUI
ttm status # pronto — daemon rodandottm link suporta claude-code, codex, opencode, gemini-cli. Ele descobre a base URL que o TUI já usa, vira upstream dela e reescreve a config do TUI pra passar pelo ttm. Também cria/preserva .ttm/context.local.json, registra a referência em AGENTS.md e CLAUDE.md, e adiciona o MCP ttm onde o TUI permite. No OpenCode, cada provider com options.baseURL ganha seu próprio target (opencode-litellm, opencode-bcm, etc.). Depois, é só reiniciar o TUI e usar normalmente — cada chamada conta tokens.

Já redireciona pra um compatível-anthropic (z.ai/GLM/...)? O
ttm linkpreserva seu redirect — ele descobre pra onde você aponta, vira upstream disso, e reescreve a config do TUI. Continua batendo no mesmo lugar, só que com contagem de tokens.
Sem npm — via git:
git clone https://github.com/cloud104/token-trace-manager
cd token-trace-manager
npm link # deixa `ttm` no PATH (sem isso, use `node bin/ttm.mjs`)Plugin do Claude Code (/plugin install): exige que o repo seja público (/plugin marketplace add cloud104/token-trace-manager clona o repo). Enquanto o repo estiver privado, use o caminho do npm acima — funciona pro Claude Code também, e o ttm link claude-code cuida de tudo (inclusive do redirect). Não há perda de função: as tools MCP (ttm_status, ttm_activate, ttm_usage_summary) ficam disponíveis em qualquer TUI compatível com MCP via .mcp.json.
No dia a dia
ttm summary --since 7d # resumo no terminal (ou /ttm:status no Claude Code)
ttm dashboard # abre o dashboard ao vivo (ou /ttm:dashboard)
ttm label PROJ-123 # muda a tarefa ativa local (ou /ttm:link PROJ-123)
ttm tokens PROJ-123 # tokens exatos da tarefa — pronto pra gestão/JiraFechando a tarefa: preenchendo o campo "tokens gastos" do ticket
A métrica principal é tokens exatos, isto é, a soma dos campos usage que o provider devolveu para a chamada. Ela não tenta estimar dinheiro nem aplicar média/peso local: tokens = entrada + cache escrito + cache lido + saída. Sai de dois jeitos:
- No dashboard: a tabela "Tokens por tarefa" tem a coluna Total e um botão copiar por linha — copia
123456 tokens exatos / 120000 lidos / 3456 escritos. A busca no topo acha a tarefa na hora. - No terminal:
ttm tokens TCW-142 --since allimprimetokens=... lidos=... escritos=...; com--rawou--bruto, imprime só o número exato para scripts.
O envio automático para o campo do Jira é a fase 2 (a base já guarda tudo por tarefa; com o MCP do Jira conectado é um comando a mais).
Auditabilidade — como confiar nos números
Os tokens não são estimados: o proxy lê o objeto usage que o próprio provedor devolve em cada resposta (o mesmo dado que fatura sua conta). O custo é a única coisa calculada localmente: tokens × tabela de preços. Para isso ser verificável (estilo Langfuse, só que 100% local), cada chamada grava:
provider_id— o id da resposta no provedor (msg_...,chatcmpl-...,resp_...): o elo para reconciliar com qualquer outra fonte.rates— o "recibo" das taxas aplicadas ($/1M por tipo de token, com a data da tabela): o custo é re-multiplicável para sempre, mesmo que a tabela mude depois.- O split de cache-write 1h vs 5m da Anthropic (TTL 1h custa 2×, não 1.25× — sem capturar isso o custo sai ~35% menor em sessões do Claude Code, que usam cache de 1h).
Duas ferramentas de verificação:
ttm audit --since 7d- Matemática interna (universal, qualquer TUI/provedor): re-multiplica tokens × taxas gravadas de cada evento e compara com o custo armazenado — divergência zero ou o comando falha.
- Reconciliação com fontes independentes — agnóstica ao harness, via adaptadores plugáveis. Cada TUI que mantém contabilidade local própria vira uma fonte; hoje:
- Claude Code: transcripts em
~/.claude/projects/— casa id a id (msg_...=provider_id), token a token. - OpenCode:
opencode.dblocal — o OpenCode não guarda o id da resposta, então casa por impressão digital (tupla exata de tokens + mesma janela de tempo, 1:1). - Eventos sem fonte local que os cubra (TUIs que não logam usage) aparecem listados como "sem fonte" — nunca somem. Novos harnesses = um adaptador novo em
lib/audit.mjs, nada mais muda.
- Claude Code: transcripts em
No dashboard, o card "Chamadas individuais (auditoria)" mostra cada request com a conta aberta no hover: 7.213 × $10/M = $0.072130 (entrada), linha a linha. A verificação externa final é a página de usage do próprio provedor (Console da Anthropic / dashboard da OpenAI), que deve bater com os agregados do período.
Exportar para Langfuse (ou qualquer backend OTel) — opcional
Rodar um Langfuse self-hosted é pesado (Postgres + ClickHouse + Redis); acoplá-lo quebraria a premissa de plugin pequeno. Em vez disso, o daemon tem um exportador OTLP nativo (~100 linhas, sem dependências, desligado por padrão): um span GenAI por chamada, com usage_details/cost_details no formato que o Langfuse ingere. Funciona com o endpoint OTel do Langfuse (cloud ou self-hosted) e com qualquer collector OTel (Grafana, Jaeger...). Para ligar, no config.json do diretório de dados:
{
"otel": {
"endpoint": "https://cloud.langfuse.com/api/public/otel",
"headers": { "Authorization": "Basic <base64(pk-lf-...:sk-lf-...)>" }
}
}Fire-and-forget: exportar nunca atrasa nem derruba o proxy, e sem o bloco otel nenhum byte sai da máquina.
Caso real que motivou isso: a primeira chamada de teste registrou $0.52; a auditoria contra o log do Claude Code confirmou os 42.880 tokens exatos, mas revelou que o cache-write era todo TTL 1h — custo verdadeiro $0.79. O split passou a ser capturado desde a v0.3.0. Eventos antigos (sem recibo/provider_id) aparecem marcados como tal no audit, nunca silenciosamente.
Testando a instalação (30 segundos, com tráfego real)
Sem mexer em nenhuma configuração: uma única chamada real do Claude Code, roteada pelo proxy só naquela invocação (a env var vale só para aquele comando), com um label de teste:
ttm start
ANTHROPIC_BASE_URL=http://127.0.0.1:25519/anthropic/TESTE-1 claude -p "responda somente: ok"
ttm summary --since 24hSaída esperada — a resposta ok do Claude e, no summary, o label TESTE-1 com tokens e custo reais:
período: 24h — 1 chamadas, 42.9k tokens, $0.52
TESTE-1 42.9k tok $0.52 (1 chamadas)Se apareceu, está tudo validado de uma vez: daemon de pé, passthrough com sua autenticação intacta, extração de usage, atribuição por label e custo calculado. Abra http://127.0.0.1:25519/dashboard para ver no navegador. (Para testar os internos sem rede: npm test — 154 asserções contra um upstream fake.)
Configurando cada TUI
O padrão é sempre o mesmo: trocar a base URL da ferramenta de targetUrl (a URL padrão do provedor) para proxyURL/{target}. Com um ticket no path (proxyURL/{target}/PROJ-123), todo o tráfego daquela configuração é atribuído ao ticket. Para slug descritivo, use proxyURL/{target}/-/meu-slug. ttm setup <tui> imprime o snippet da sua porta atual.
Claude Code
targetUrl padrão: https://api.anthropic.com — override por env var ANTHROPIC_BASE_URL (precisa existir antes do processo iniciar):
// ~/.claude/settings.json (todas as sessões) ou .claude/settings.json do repo:
{ "env": { "ANTHROPIC_BASE_URL": "http://127.0.0.1:25519/anthropic" } }
// por repositório, com ticket embutido:
{ "env": { "ANTHROPIC_BASE_URL": "http://127.0.0.1:25519/anthropic/PROJ-123" } }Atenção: desde a v2.1.196, apontar
ANTHROPIC_BASE_URLpara fora deapi.anthropic.comdesativa o Remote Control do Claude Code. A autenticação (inclusive OAuth de assinatura) continua funcionando — o proxy repassa tudo intacto. E o/ttm:setupfaz essa edição para você, com sua aprovação.
Codex (OpenAI)
targetUrl padrão: https://api.openai.com/v1, protocolo Responses API — override no ~/.codex/config.toml (o config de projeto ignora esta chave):
model_provider = "ttm"
[model_providers.ttm]
name = "OpenAI via ttm"
base_url = "http://127.0.0.1:25519/codex"
wire_api = "responses"
requires_openai_auth = true
[mcp_servers.ttm]
command = "node"
args = ["/caminho/do/token-trace-manager/lib/mcp-server.mjs"]Prefira
model_providersaopenai_base_url/OPENAI_BASE_URL: há releases do Codex com bug que ignora essas formas (issue #16719). O proxy TTM não precisa de API key: ele só repassa os headers que o Codex enviar. Para o provider criado pelottm link codex, seOPENAI_API_KEYexistir no ambiente o TTM usaenv_key; caso contrário usarequires_openai_auth = truepara aproveitar a autenticação normal do Codex.
OpenCode (sst)
Multi-provider — caminho recomendado:
ttm link opencodeO comando lê o opencode.json/opencode.jsonc que já tem seus providers reais
(litellm, bcm, OpenRouter, etc.), preserva cada upstream no TTM, troca o
baseURL de cada provider para um proxy local próprio e registra o MCP ttm. Assim, trocar de modelo/provider dentro do OpenCode continua passando pelo TTM. Se o OpenCode
ainda não tiver provider com options.baseURL, o link falha em vez de inventar
um provider.
Gemini CLI (Google)
targetUrl padrão: https://generativelanguage.googleapis.com — override por env var (http permitido para 127.0.0.1):
export GEMINI_API_KEY=sua-chave
export GOOGLE_GEMINI_BASE_URL="http://127.0.0.1:25519/gemini"Limitação: só o modo API key é rastreável. No login OAuth pessoal, o Gemini CLI usa o backend interno Code Assist (
cloudcode-pa.googleapis.com), que essa variável não afeta.
Kilo Code
targetUrl padrão: gateway próprio (api.kilo.ai) — para rastrear, use um provider OpenAI-compatible no kilo.jsonc ou na UI (Settings → Providers → Custom Provider → Base URL):
{
"provider": {
"openai-compatible": {
"options": { "apiKey": "{env:OPENAI_API_KEY}", "baseURL": "http://127.0.0.1:25519/openai/v1" }
}
}
}Goose (Block)
export OPENAI_HOST="http://127.0.0.1:25519/openai" # provider OpenAI-compatible
export ANTHROPIC_HOST="http://127.0.0.1:25519/anthropic" # provider AnthropicCrush (Charm)
crush.json (ou ~/.config/crush/crush.json):
{
"providers": {
"ttm-anthropic": { "type": "anthropic", "base_url": "http://127.0.0.1:25519/anthropic/v1", "api_key": "$ANTHROPIC_API_KEY" },
"ttm-openai": { "type": "openai-compat", "base_url": "http://127.0.0.1:25519/openai/v1", "api_key": "$OPENAI_API_KEY" }
}
}Aider
export OPENAI_API_BASE="http://127.0.0.1:25519/openai/v1"
# ou: aider --openai-api-base http://127.0.0.1:25519/openai/v1Cline / Roo Code
Só via interface: Settings → API Provider = "OpenAI Compatible" → Base URL = http://127.0.0.1:25519/openai/v1.
Droid (Factory AI)
~/.factory/settings.json:
{ "customModels": [{ "model": "claude-opus-4-8", "provider": "anthropic", "baseUrl": "http://127.0.0.1:25519/anthropic", "apiKey": "${ANTHROPIC_API_KEY}" }] }GitHub Copilot CLI (modo BYOK)
export COPILOT_PROVIDER_BASE_URL="http://127.0.0.1:25519/openai/v1"
export COPILOT_PROVIDER_TYPE=openai
export COPILOT_MODEL=gpt-5.5
export COPILOT_PROVIDER_API_KEY=sua-chaveO modo padrão (backend proprietário do Copilot) não é rastreável.
Não suportados (sem override documentado de base URL)
- Amp (Sourcegraph) — roteia modelos pelo backend proprietário;
HTTP_PROXYé só transporte. - Cursor CLI — o
cursor-agentfala com o backend da Cursor; o BYOK da IDE não vale para o CLI. - Kiro CLI (AWS) — nenhum mecanismo documentado.
Labels (atribuição por ticket)
O destino normal da tarefa fica no próprio repo, em .ttm/context.local.json:
{
"active_label": "PROJ-123"
}ttm link cria esse arquivo local e insere uma referência curta em AGENTS.md e CLAUDE.md, para o agente saber que pode ler/alterar active_label e chamar ttm_activate quando o usuário trocar de tarefa. No Linux/WSL, o proxy tenta descobrir o CWD do processo que chamou a API e usa o .ttm/context.local.json daquele repo; quando isso não está disponível, o target criado pelo ttm link também guarda o caminho do arquivo como fallback.
Formas de atribuição, por ordem de prioridade:
- Label explícito na URL:
http://127.0.0.1:25519/anthropic/PROJ-123— aquela chamada cai noPROJ-123. Para um label que não é ticket, usehttp://127.0.0.1:25519/anthropic/-/meu-slug. - Contexto local do repo:
.ttm/context.local.jsoncomactive_label. É o caminho para Codex/OpenCode/Claude em vários repos, porque a tarefa acompanha o repo atual e pode ser trocada pelo agente via MCP. - Compatibilidade legada:
ttm label PROJ-123ou MCPttm_set_labeltambém atualizam o contexto local e o estado do daemon para clientes antigos.
Chamadas sem nenhum label aparecem no dashboard como "Sem label" — nada se perde.
A ideia é fechar custo por tarefa localmente. Enviar os agregados para o campo do ticket no Jira é uma fase futura (a base já registra tudo por label).
As páginas do proxy (ao vivo, só em 127.0.0.1)
| Página | O que tem |
|---|---|
| /dashboard | Visão geral: KPIs lidos/escritos, tabela "Tokens por tarefa" (share, sparkline, botão copiar no hover), quebras por provedor/modelo/cliente/dia, chamadas recentes. |
| /traces | Inspetor estilo Langfuse: sessões (agrupadas por cliente + tarefa + janela de inatividade de 30min) → expande para as mensagens uma a uma — entrada, cache escrito (5m/1h), cache lido, saída, custo com o recibo aberto no hover, duração, id no provedor (clique copia) e o botão conteúdo, que abre o payload da chamada: sistema, mensagens (papel a papel) e a resposta do modelo. Filtros por período, provedor, modelo, cliente e tarefa. |
| /config | Retenção dos traces (padrão 24h, editável; 0 = nunca apagar), botões de limpeza/deleção e resumo da configuração. |
APIs JSON para automações: GET /api/summary (com tasks), /api/traces, /api/events, /api/payload?id=N (request/response da chamada), /api/label, /api/config, /healthz; POST /api/retention, /api/purge, /api/settings. ttm dashboard --out relatorio.html exporta a visão geral como HTML estático.
Retenção e histórico
Tudo fica num SQLite interno (~/.claude/plugins/data/token-trace-manager/ttm.sqlite), que sobrevive a upgrades do plugin. Duas camadas com vidas diferentes:
- Traces detalhados (mensagem a mensagem): retidos por 24h por padrão — ajuste na página
/config(até 1 ano, ou0para nunca apagar). Um job de hora em hora expira os antigos. - Histórico por tarefa: ao expirar, cada trace é somado num rollup diário por tarefa/modelo/provedor antes de ser apagado — o total que vai pro campo do Jira nunca se perde, só o detalhe individual. O dashboard mistura as duas camadas automaticamente, sem dupla contagem (um rollup só existe para traces já apagados).
- Conteúdo das chamadas (
payloads/<id>.json): request completo (sistema + mensagens) e o texto da resposta, para o drill-down da página Traces. Vive e morre com o trace correspondente (retenção e deleções removem os JSONs juntos). Toggle na/config. - Deleção sob demanda na
/config: apagar todos os traces (mantendo o histórico), ou apagar tudo — inclusive por tarefa específica viaPOST /api/purge {"mode": "...", "label": "PROJ-123"}.
Servidor MCP
O mesmo servidor funciona em qualquer cliente MCP e sobe o daemon sozinho quando necessário:
| Tool | O que faz |
|---|---|
| ttm_status | daemon rodando?, porta, tarefa ativa local/daemon, targets, URL do dashboard |
| ttm_activate | grava .ttm/context.local.json, ativa a tarefa no proxy e detecta repo/branch |
| ttm_set_label | define/limpa a tarefa ativa local e o estado do daemon |
| ttm_usage_summary | resumo por label/provedor/modelo/dia (since, label) |
| ttm_dashboard_url | garante o daemon de pé e retorna a URL do dashboard |
No Claude Code vem junto com o plugin. No OpenCode, ttm link opencode escreve isso automaticamente no opencode.json/opencode.jsonc que já contém seu provider real:
// opencode.json
{ "mcp": { "ttm": { "type": "local", "command": ["node", "/caminho/do/repo/lib/mcp-server.mjs"], "enabled": true } } }CLI
ttm start | stop | status gerencia o daemon
ttm hint [--since 24h] linha compacta: ttm active | task | tokens | dash
ttm statusline [--since 24h] mesma linha, sem subir daemon se estiver parado
ttm label <TICKET-123|none> tarefa ativa local (.ttm/context.local.json)
ttm summary [--since 7d] resumo no terminal
ttm dashboard [--since 7d] [--out arquivo.html]
ttm tokens <TICKET> [--since] [--raw] [--bruto] tokens exatos da tarefa
ttm audit [--since 7d] auditoria: matemática interna + fontes independentes
ttm targets lista os upstreams registrados
ttm config [porta <n>] mostra config / troca a porta
ttm setup <tui> snippet de configuração por ferramentaHint discreto de tarefa
Para lembrar o humano sem poluir o TUI, o ttm usa uma linha única, própria para
statusline, toast ou contexto de hook. O número de tokens nessa linha usa o
total exato reportado pelo provider:
ttm active | task PROJ-123 | tokens 48.2k | dash http://127.0.0.1:25519/dashboardttm hintsobe o daemon se necessário e imprime a linha.ttm statuslinesó consulta o estado atual; se o daemon estiver parado, imprimettm off | task none | tokens 0 | dash ....- Tokens exatos: entrada + cache lido + cache escrito + saída, sem média, peso local ou conversão financeira.
- No Claude Code, o plugin registra um
UserPromptSubmitque roda no início da sessão: ele injeta essa linha e orienta o agente a perguntar se deve manter ou trocar a tarefa. Depois fica silencioso; só a cada 200 prompts do usuário injeta um checkpoint raro para confirmar se a tarefa ainda é a mesma. Não bloqueia o prompt. - No OpenCode/Codex,
ttm linkregistra o MCP quando o TUI permite e insere a referência emAGENTS.md/CLAUDE.md; o agente pode trocar a tarefa chamandottm_activatesem abrir outro terminal.
Configuração avançada
Arquivo: ~/.claude/plugins/data/token-trace-manager/config.json (criado sob demanda):
{
"port": 25519,
"injectUsage": true, // injeta include_usage em streams OpenAI sem usage (e filtra o chunk extra)
"targets": {
"meugateway": { "targetUrl": "https://llm.minhaempresa.com/api", "protocol": "openai" }
}
}- Protocolos suportados:
anthropic,openai(chat completions e Responses API, detectado pelo path),openai-responses,gemini. injectUsage: streams de chat completions semstream_options.include_usagenão trazem usage. O proxy injeta a opção na request e remove o chunk extra da resposta antes de repassar (SDKs oficiais toleram o chunk, mas wrappers comuns — LangChain, Haystack — quebram; por isso o filtro). Se o cliente já pediuinclude_usage, nada é alterado.- Preços: tabela em
lib/pricing.mjs(Anthropic/OpenAI/Gemini, coletados das páginas oficiais em 2026-07-06). Modelos fora da tabela têm custonull— os tokens são registrados mesmo assim e o dashboard sinaliza custo parcial. Override sem tocar em código:pricing.override.jsonno diretório de dados, ex:{ "meu-modelo": { "input": 2.0, "output": 8.0 } }(USD/1M tokens).
Comandos do plugin (Claude Code)
| Comando | O que faz |
|---|---|
| /ttm:setup [tui] | configura o Claude Code para passar pelo proxy (edita settings com sua aprovação) ou mostra o snippet de outro TUI |
| /ttm:status | estado do daemon + resumo de uso/custo |
| /ttm:link PROJ-123 | ativa/troca a tarefa |
| /ttm:dashboard | abre o dashboard local |
| /ttm:config | mostra porta, targets e tarefa ativa; explica como ajustar |
O plugin do Claude Code também carrega o hook de hint descrito na seção CLI.
Testes
node test/e2e.mjsSobe um upstream fake + o daemon real e valida: passthrough de streaming e não-streaming nos 4 protocolos, labels por URL e por contexto local, normalização de tokens (cache/reasoning), cálculo de custo, injeção+filtragem de include_usage, endpoints locais, dashboard, privacidade (headers e segredos no body não persistem) e regressões adversariais (XSS via User-Agent, corrupção por $' no template, rotas herdadas de protótipo, paths hifenizados, erros de protocolo MCP). 193 asserções, cobrindo também retenção/rollups, contexto repo/branch, relabel retroativo, sessionização de traces, backend JSON e o exportador OTel.
Upgrade
Versionamento semver em .claude-plugin/plugin.json. Como plugin:
/plugin update ttm (reinicie o Claude Code para aplicar)Standalone: git pull e ttm stop && ttm start.
Limitações conhecidas
- O TUI precisa suportar override de base URL (ver lista de não suportados acima).
- Se o daemon estiver parado, o TUI configurado fica sem resposta —
ttm startresolve; o servidor MCP e o CLI sobem o daemon automaticamente. - Preços de modelos mudam; a tabela é estática com data marcada (
ttm configmostra) e override viapricing.override.json. - Gemini CLI: só modo API key (OAuth usa backend interno não roteável).
- O custo do Sonnet 5 usa o preço introdutório ($2/$10) válido até 2026-08-31 — atualizar para $3/$15 depois disso.
