diff --git a/package.json b/package.json index df1bbfd6..167848ee 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,8 @@ "zh-TW", "zh-CN", "ja", - "ko" + "ko", + "pt-BR" ], "default": "auto", "description": "Display language (auto-detection or manual selection). All other settings now live in the dashboard's ⚙ Settings tab (Show Usage Details)." diff --git a/src/adviceDemoSample.ts b/src/adviceDemoSample.ts index 92da7b47..40ff323c 100644 --- a/src/adviceDemoSample.ts +++ b/src/adviceDemoSample.ts @@ -321,13 +321,64 @@ Warum: Gibt Claude eine Entscheidungsgrenze, nicht ein Dutzend. Sonnet 4.6 bei ausreichender Qualität. `; +const PT_BR = `## Resumo + +Nos últimos 30 dias, **as respostas do assistente e os resultados de ferramentas dominam +seus gastos** (≈68% combinados), enquanto seus próprios prompts representam apenas ≈11%. +O padrão: prompts curtos e exploratórios como *"dá uma olhada em..."* disparam várias +chamadas Read/Grep que inflam os tokens de saída. + +A principal alavanca é a **precisão dos prompts**, não "usar um modelo menor". + +## Reescritas concretas + +### 1. Enquadramento "explore primeiro" + +**Antes:** *"Dá uma olhada no módulo de autenticação e me diz o que está acontecendo."* + +**Depois:** *"Em \`src/auth/session.ts\`, \`refreshToken()\` está retornando 401 +intermitentemente em produção. Leia este arquivo e seus chamadores diretos, depois +proponha uma correção. Não resuma o módulo inteiro."* + +Por quê: indica o *sintoma*, nomeia o *escopo* e suprime o resumo desnecessário. + +### 2. Desvio de escopo durante a tarefa + +**Antes:** *"Ah, pode também confirmar que os testes ainda passam? E adicionar um teste +para o caso extremo que discutimos?"* + +**Depois:** *"Adicione **um** teste para o caso de array vazio em \`parseConfig\`. +Execute apenas \`npm test -- parseConfig.test.ts\`. Não adicione outros testes."* + +Por quê: limita a mudança, o comando de teste e a área de impacto. + +### 3. "Use seu julgamento" + +**Antes:** *"Refatore isso da forma que achar mais limpa."* + +**Depois:** *"Extraia a lógica de retry de \`processBatch\` para um helper +\`retryWithBackoff\`. Mantenha todo o resto igual. Não renomeie variáveis."* + +Por quê: dá ao Claude uma única decisão a tomar, não uma dúzia. + +## Economias menores + +- **Taxa de acerto do cache: 41%** — bom. Não quebre o cache editando CLAUDE.md + no meio da session; edite entre sessions. +- **Context window médio ao final da session: 89k tokens.** Sessions acima de ~140k ficam + exponencialmente mais caras por turno — inicie novas sessions mais cedo. +- **Haiku 4.5 aparece em 0% das suas sessions.** Para reformatar, comentar ou "explica + essa linha", ele custa ~1/15 de Sonnet 4.6 com qualidade suficiente. +`; + const BODIES: Record = { 'en': EN, 'zh-CN': ZH_CN, 'zh-TW': ZH_TW, 'ja': JA, 'ko': KO, - 'de-DE': DE + 'de-DE': DE, + 'pt-BR': PT_BR }; /** Demo body for the user's UI language; falls back to English. */ diff --git a/src/i18n.ts b/src/i18n.ts index 76000774..e264ab2a 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -1477,6 +1477,221 @@ const translations: Record = { decimalPlaces: '소수점 자릿수', }, }, + 'pt-BR': { + statusBar: { + loading: 'Carregando...', + noData: 'Sem dados do Claude Code', + notRunning: 'Claude Code não está em execução', + error: 'Erro', + currentSession: 'Sessão', + }, + popup: { + title: 'Uso do Claude Code', + currentSession: 'Sessão atual', + today: 'Hoje', + thisMonth: 'Este mês', + allTime: 'Todo o período', + workspaceToday: 'Este projeto', + refresh: 'Atualizar', + autoRefresh: 'Atualização automática', + settings: 'Configurações', + settingsTab: 'Configurações', + settingsIntro: + 'As configurações agora ficam aqui. Apenas idioma, diretório de dados e chave de API permanecem nas Configurações do VS Code (para sincronizar). As alterações são aplicadas imediatamente.', + settingsResetAll: 'Restaurar tudo para os padrões', + settingsGroupGeneral: 'Geral', + settingsGroupStatusBar: 'Barra de status', + settingsGroupData: 'Dados e atualização', + settingsGroupAdvice: 'Conselho de IA e Optimizer', + totalTokens: 'Total de tokens', + inputTokens: 'Tokens de entrada', + outputTokens: 'Tokens de saída', + cacheCreation: 'Cache de entrada (Miss)', + cacheRead: 'Cache de entrada (Hit)', + cost: 'Custo', + messages: 'Mensagens', + modelBreakdown: 'Uso por modelo', + dailyBreakdown: 'Uso diário', + monthlyBreakdown: 'Uso mensal', + hourlyBreakdown: 'Uso por hora', + sessions: 'Sessões', + sessionBreakdown: 'Uso por sessão', + project: 'Projeto', + startTime: 'Início', + duration: 'Duração', + hour: 'Hora', + projects: 'Projetos', + projectBreakdown: 'Uso por projeto', + fullPath: 'Caminho completo', + peakContext: 'Pico de contexto', + tokenComposition: 'Composição de tokens', + lastActive: 'Última atividade', + pricing: 'Preços', + refreshPricing: 'Atualizar preço dos tokens', + pricingUpdated: 'Preços atualizados', + pricingUpdateFailed: 'Falha ao atualizar preços', + sortHint: 'Clique no cabeçalho da coluna para ordenar', + quota: 'Cota', + quotaWindow: 'Janela', + quotaLimit: 'Limite', + quota5h: '5 horas', + quotaWeekly: 'Semanal', + quotaHint: 'Dados reais da Anthropic /usage.', + contextWindow: 'Janela de contexto', + contextHint: 'Nova tarefa → /clear', + contextHintCompact: 'Mesma tarefa → /compact', + contextLeft: 'Contexto restante', + contentAnalysis: 'Conteúdo', + estimatedNote: 'Estimado pelo tamanho do texto — as proporções relativas são confiáveis; os valores absolutos são aproximados.', + calibratedNote: 'Calibrado: as proporções por categoria vêm do tamanho do texto, ajustadas aos totais exatos de tokens cobrados (lado da saída / lado da entrada + escrita de cache). Alterne com analysis.calibrate.', + calibratedTokens: 'Tokens calibrados', + thinkingTokensCalibrated: 'tokens reais de raciocínio (calibrado)', + byTool: 'Resultados de ferramentas por ferramenta', + catUserPrompts: 'Seus prompts', + catAssistantText: 'Respostas do assistente', + catAssistantThinking: 'Raciocínio do assistente', + catToolCalls: 'Chamadas de ferramenta', + catToolResults: 'Resultados de ferramenta', + estTokens: 'Tokens estimados', + share: 'Proporção', + resets: 'Reinicia em', + cacheHitRate: 'Taxa de acerto do cache', + last30days: 'Últimos 30 dias', + branches: 'Branches', + branchBreakdown: 'Uso por branch', + branch: 'Branch', + workflows: 'Workflows', + workflowBreakdown: 'Uso por workflow', + workflowName: 'Workflow', + model: 'Modelo', + agents: 'Agentes', + agent: 'Agente', + workflowsThisMonth: 'Workflows neste mês', + workflowCostShare: 'do custo deste mês', + workflowCacheHint: + 'Taxa de acerto do cache = leituras de cache ÷ todos os tokens do lado da entrada. Workflows nativos do Claude reaproveitam o cache de prompt entre agentes (taxa alta); um provedor sem cache entre agentes mostra ~0% — o mesmo workflow custa desproporcionalmente mais nele.', + adhocBadge: 'subagentes (ad-hoc)', + workflowModeBadge: 'workflow', + workflowModeHint: + '"workflow" = um diretório de execução de workflow dinâmico em disco; "subagentes (ad-hoc)" = um disparo simples da ferramenta Task. O nível de esforço (ultracode/xhigh) não é registrado nos logs, então nenhum dos selos afirma um.', + workflowNativeHint: + 'O ultracode nativo do Claude muitas vezes mantém a orquestração na sessão principal (sem arquivos de agente), então aparece em Sessões / Uso em vez de como uma linha aqui. Execuções que gravam arquivos de agente mostram seu custo Claude na linha de orquestração. (Previsto para uma versão futura.)', + orchestration: 'orquestração na sessão principal', + commonTaskPrefix: 'Texto de tarefa compartilhado', + thinkingShare: '% de raciocínio', + effortHint: 'Alta proporção de raciocínio — considere /effort high em vez de xhigh para tarefas como esta.', + quotaWarnBanner: + 'Resta apenas {remaining}% da sua janela de 5 horas. Uma execução de workflow pode consumir grande parte dela — considere esperar o reset: execuções interrompidas perdem o cache de prompt e refazem ~40% mais caro.', + dismiss: 'Dispensar', + attribution: 'Acompanhamento de uso', + attrDisclaimer: + 'Aproximado, baseado nas sessões locais desta máquina — não inclui outros dispositivos nem o claude.ai. São características independentes do seu uso, não uma decomposição.', + attrLargeContext: '{pct}% do seu uso foi com contexto >150k', + attrLargeContextShort: 'contexto >150k', + attrLargeContextHint: + 'Sessões mais longas são mais caras mesmo com cache. Use /compact no meio da tarefa e /clear ao mudar para novas tarefas.', + attrLongSessions: '{pct}% do seu uso veio de sessões ativas por 8+ horas', + attrLongSessionsShort: 'sessões de 8h+', + attrLongSessionsHint: + 'Costumam ser sessões em segundo plano/loop. O uso contínuo soma rápido, então confirme se é intencional.', + attrSubagentHeavy: '{pct}% do seu uso veio de sessões com muitos subagentes', + attrSubagentHeavyShort: 'Sessões com muitos subagentes', + attrSubagentHeavyHint: + 'Cada subagente executa suas próprias requisições. Seja deliberado ao criá-los — e considere um modelo mais barato para subagentes mais simples.', + attrWorkflows: '{pct}% do seu uso veio de execuções de workflow', + attrWorkflowsShort: 'Execuções de workflow', + attrWorkflowsHint: 'Veja a aba Workflows para detalhes por execução e taxas de acerto de cache.', + attrSkillChar: '{pct}% do seu uso veio de {name}', + attrSkillCharHint: 'Skills pesadas podem ter o escopo reduzido ou rodar com um modelo mais barato via frontmatter da skill.', + attrPluginChar: '{pct}% do seu uso veio do plugin "{name}"', + attrPluginCharHint: + 'Revise o que este plugin contribui — seus agentes, skills e ferramentas MCP contam para o seu limite.', + attrSkills: 'Skills', + attrSubagents: 'Subagentes', + attrPlugins: 'Plugins', + attrModels: 'Modelos', + attrShare: '% do uso', + count: 'Quantidade', + scopeDay: 'Dia', + scopeWeek: 'Semana', + scopeMonth: 'Mês', + attrTodayPointer: 'Detalhes: aba Conteúdo', + sessionTitle: 'Sessão', + sessionActions: 'Ações', + copySessionId: 'Copiar ID da sessão', + copyPath: 'Copiar caminho', + resumeSession: 'Retomar sessão', + resumeInvalid: 'ID de sessão inválido — não é possível retomar.', + sessionFilterCurrent: 'Projeto atual', + sessionFilterAll: 'Todos', + deleteSession: 'Excluir sessão', + deleteSessionConfirm: 'Excluir a sessão "{name}"?', + deleteSessionDetail: 'O log da conversa vai para a lixeira (recuperável). A extensão é somente leitura no restante.', + deleteSessionYes: 'Excluir', + deleteSessionNotFound: 'Arquivo de log da sessão não encontrado.', + deleteSessionDone: 'Sessão "{name}" excluída (movida para a lixeira).', + getAdvice: 'Obter conselho de IA', + adviceCardTitle: 'Conselho de IA', + adviceCardDesc: + 'Envie o resumo do seu uso + uma amostra dos seus próprios prompts ao seu modelo e receba dicas concretas para escrever instruções mais claras e reduzir desperdício.', + optimizerTitle: 'Otimizador de uso', + optimizerDesc: + 'Transforme um pedido rascunhado e malformado em um prompt limpo para colar direto no Claude Code — além de um esforço / raciocínio / modelo sugeridos para a tarefa.', + optimizerHowto: + 'Digite ou cole seu rascunho abaixo, marque quaisquer ajustes opcionais e clique em Otimizar. Apenas o texto que você cola é enviado ao seu modelo — nunca ao Claude Code nem ao seu terminal.', + optimizerConsent: + 'O Otimizador de Uso envia o texto que você cola ao modelo de API configurado. Nada é enviado ao Claude Code e nada é digitado em um terminal. Continuar?', + optimizerEnableBtn: 'Ativar nas configurações', + optimizerPlaceholder: 'Cole um prompt rascunhado para otimizar…', + optimizerRun: 'Otimizar', + optimizerRunning: 'Otimizando…', + optimizerCopy: 'Copiar prompt', + optimizerCopied: 'Copiado', + optimizerResolve: 'Sinalizar referências vagas', + optimizerResolveHint: + 'Faça o modelo apontar referências vagas (ex.: "isto", "o arquivo", "aquele bug") e defini-las ou marcar uma suposição clara.', + optimizerDistil: 'Condensar texto longo colado', + optimizerDistilHint: + 'Se o seu rascunho cola logs / código / docs longos, condense-os ao que o Claude realmente precisa.', + optimizerAesthetic: 'Sugerir uma direção de estilo', + optimizerAestheticHint: + 'Para tarefas de UI / visuais / de escrita, proponha uma direção de estilo concreta para o resultado não ficar genérico.', + optimizerPromptHeading: 'Prompt otimizado', + optimizerSettingsHeading: 'Configurações de execução recomendadas', + experimentalBadge: 'experimental', + adviceNeedsKey: 'Defina uma chave de API nas configurações para usar o conselho de IA.', + adviceGenerating: 'Gerando conselho de uso…', + adviceFailed: 'Falha ao obter conselho', + adviceScopeOverall: 'Geral (todos os projetos)', + adviceScopePrompt: 'Escolha o foco do conselho', + adviceDemoButton: 'Ver demonstração', + adviceDemoNotice: + '# DEMO — Prévia do conselho de uso de IA\n\n' + + '> **Este arquivo é uma demo estática, não um conselho real.**\n' + + '> O texto abaixo foi escrito manualmente para ilustrar o tipo de saída\n' + + '> que o recurso produz. Ele **não** é baseado nos seus dados reais de uso\n' + + '> do Claude Code — nada foi enviado a nenhuma API para gerar isso.\n\n' + + '### Para obter um conselho real e personalizado com base no SEU uso:\n\n' + + '1. Abra as Configurações (`Ctrl+,` / `Cmd+,`)\n' + + '2. Pesquise por **`claudeCodeUsage.advice.apiKey`**\n' + + '3. Cole uma chave de API compatível com OpenAI — DeepSeek funciona direto\n' + + ' ([deepseek.com](https://platform.deepseek.com))\n' + + '4. Execute novamente **`Claude Code Usage: Get AI Usage Advice`**', + costComposition: 'Composição de custos', + date: 'Data', + yesterday: 'Ontem', + dataDirectory: 'Diretório de dados', + noDataMessage: 'Nenhum dado de uso encontrado. Verifique se o Claude Code está em execução e configurado corretamente.', + errorMessage: 'Erro ao carregar os dados de uso. Verifique sua configuração.', + }, + settings: { + title: 'Configurações de uso do Claude Code', + refreshInterval: 'Intervalo de atualização (segundos)', + dataDirectory: 'Caminho do diretório de dados', + language: 'Idioma', + decimalPlaces: 'Casas decimais', + }, + }, }; // Per-setting label / help translations for the dashboard ⚙ Settings panel. @@ -1635,6 +1850,34 @@ const SETTINGS_I18N: Partial dir; trigger word "ultracode"), or