brito-cli 0.7.4 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.pt-BR.md CHANGED
@@ -1,262 +1,301 @@
1
- # Brito
2
-
3
- [English](README.md) · **Português**
4
-
5
- > Um agente de código para o seu terminal (`brito-cli`) e para o seu desktop (um app nativo) que conhece o seu projeto como um **grafo** e aprende os procedimentos dele como **skills que você revisa**.
6
-
7
- O Brito é um agente para desenvolvimento de software. Use no terminal (`brito-cli` no npm) ou como app de desktop (um executável para macOS, Windows e Linux): o mesmo agente, o mesmo grafo, as mesmas skills. Em vez de dar `grep` e ler arquivos às cegas, ele mantém um **grafo de conhecimento do código** (símbolos, quem chama quem, quem importa quem) e responde perguntas como *"o que quebra se eu mudar isto?"* direto do grafo, em uma fração de segundo. Ele também guarda **notas de memória** e **skills**: procedimentos reutilizáveis aprendidos no seu próprio trabalho, que só passam a valer depois que **você** aprova.
8
-
9
- ![Brito respondendo uma pergunta com o grafo de código](docs/images/answer-with-graph.png)
10
-
11
- *Uma sessão real num pequeno projeto SvelteKit: uma pergunta, duas consultas ao grafo (0,1 s e 0,0 s) e uma resposta que já inclui os componentes `.svelte` que dependem do arquivo. A barra de status mostra o custo real do turno.*
12
-
13
- ## Destaques
14
-
15
- > **Atualizando para a 0.6:** o motor do grafo mudou do Kùzu (descontinuado) para o LadybugDB. O grafo é reconstruído sozinho no primeiro uso; o seu `.brito/graph.kuzu` antigo é mantido. O Brito pergunta uma vez se copia as suas notas (memória) para o grafo novo, ou rode `brito migrar-notas` quando quiser. Os testes rodam no CI em macOS, Linux e Windows (use a 0.6.1 ou posterior no Windows/Linux). Veja o [CHANGELOG](CHANGELOG.md).
16
-
17
- - **Exploração guiada pelo grafo.** `graph_search`, `graph_context`, `graph_callers`, `graph_callees` e `graph_impact` respondem "onde está, quem usa, o que quebra" sem ler arquivos inteiros. O grafo é embutido ([LadybugDB](https://github.com/LadybugDB/ladybug), fork mantido do Kùzu), local e incremental.
18
- - **Cobertura ampla.** TypeScript/JavaScript, Python e os blocos de script de componentes `.svelte`, `.vue` e `.astro`. Aliases de import (`paths` do tsconfig, `imports` do package.json, `$lib` do SvelteKit) viram arestas de verdade. O que o `.gitignore` ignora fica de fora.
19
- - **Skills que aprendem sozinhas, em período de teste.** Depois de uma tarefa em que algo tropeçou ou foi corrigido, o Brito reflete e cria uma skill *em teste* sem te interromper. A skill se prova pelo uso: 3 usos limpos a promovem, 2 tropeços a arquivam (recuperável). O que é arriscado, ou qualquer mudança numa skill que você aprovou, continua esperando o seu `/skills approve`. `BRITO_SKILLS=ask` volta a pedir aprovação para tudo; `off` desliga o aprendizado.
20
- - **Proteções sobre o que é aprendido.** Um lint rejeita segredos, credenciais embutidas em URL, `curl | sh` e frases de injeção de prompt, e **avisa sobre comandos destrutivos** (veja abaixo).
21
- - **Modos de permissão.** manual, auto-edições, plano e "tudo liberado" (`Shift+Tab` alterna). As skills autônomas não dependem do modo: nascem em teste e são julgadas pelo resultado.
22
- - **Dois backends, uma interface.** Use uma chave da API da Anthropic ou a sua assinatura do Claude Code pela CLI `claude`. O Brito nunca lê nem envia o token da sua assinatura.
23
- - **Terminal ou app de desktop.** `npm i -g brito-cli` instala o comando `brito`; o app de desktop é um executável nativo com janela (projetos e sessões numa barra lateral, chat, pedidos de permissão), sem precisar de Node nem de terminal. Veja [Instalação](#instalação).
24
- - **Imagens.** Arraste um arquivo de imagem para o prompt (ou cole o caminho) e ele é anexado ao turno: PNG, JPEG, GIF ou WebP, até 5 MB.
25
- - **Subagentes.** `explore`, `plan` e `general` rodam em contextos isolados (os somente-leitura, em paralelo); crie os seus em `.brito/agents/*.md`.
26
- - **Servidor MCP.** `brito mcp-serve` expõe grafo, memória e skills a outros clientes MCP, como o Claude Code. As tools de consulta são marcadas `alwaysLoad`, para não ficarem escondidas atrás da busca de tools.
27
-
28
- ## Como funciona
29
-
30
- ![Indexação uma vez, depois respostas vindas do grafo em vez de grep e leitura de arquivos](docs/images/graph-vs-grep.pt-BR.svg)
31
-
32
- *O grafo é construído uma vez e atualizado de forma incremental; uma pergunta como "o que quebra se eu mudar isto?" vira uma ou duas chamadas ao grafo.*
33
-
34
- ```mermaid
35
- flowchart LR
36
- code["Seu projeto<br/>.ts · .js · .py · .java · .kt · .go · .rb · .php · .cs · .rs · .svelte · .vue · .astro"] -->|"tree-sitter<br/>incremental"| cg[("Grafo de código<br/>símbolos · chamadas · imports")]
37
- cg <-->|"graph_search · graph_callers<br/>graph_impact · graph_context"| agent{{"Agente Brito"}}
38
- mem[("Memória<br/>decisões · convenções")] <-->|"recall / remember"| agent
39
- agent -->|"após uma tarefa complexa"| learn["Reflexão"]
40
- learn -->|"propõe"| pending["Skills pendentes"]
41
- pending -->|"/skills approve<br/>você decide"| skills[("Skills<br/>.brito/skills")]
42
- skills -->|"skill_load"| agent
43
- ```
44
-
45
- - **Grafo de código**: funções, classes, métodos e componentes como nós; `CALLS` e `IMPORTS` como arestas. Só reparseia os arquivos cujo hash mudou e se atualiza sozinho após edições.
46
- - **Memória**: notas duráveis (decisões, convenções, bugs descobertos) ligadas a arquivos e símbolos, recuperadas com `recall`.
47
- - **Skills**: procedimentos passo a passo para o *seu* projeto (comandos, ordem, armadilhas, como verificar). O agente carrega uma com `skill_load` antes de uma tarefa que ela cobre.
48
- - **Journal**: o Brito lembra entre sessões quais tarefas se repetiram, o melhor indício de que um procedimento é geral e vale guardar.
49
-
50
- ### Arquitetura em uma imagem
51
-
52
- ![Arquitetura do Brito: contexto, permissões, ferramentas e subagentes ao redor do modelo](docs/images/architecture.pt-BR.svg)
53
-
54
- *Tudo o que o modelo vê ou pode fazer é um dos oito componentes, agrupados por papel. O texto em monoespaçado é o arquivo ou comando real; a etiqueta diz quando ele entra em ação.*
55
-
56
- ## Skills que merecem o lugar
57
-
58
- ![Ciclo de vida da skill: tarefa, reflexão, teste ou pendente, ativa ou arquivada](docs/images/skill-lifecycle.pt-BR.svg)
59
-
60
- *Os dois caminhos de uma skill. As seguras se provam em teste; as arriscadas esperam a sua aprovação.*
61
-
62
- ![Revisando uma skill pendente, com aviso de comando destrutivo](docs/images/skills-review.png)
63
-
64
- 0. **Caminho autônomo (padrão).** A reflexão grava a skill nova como *em teste*, marcada "(em teste)" no índice. Cada turno que a carrega conta como vitória (sem erro→conserto nem correção do usuário) ou falha. 3 vitórias (e no máximo 1 falha a cada 3 vitórias) a promovem; 2 falhas sem mais vitórias, ou 21 dias sem uso, a arquivam em `.brito/skills/.trash`. O Brito imprime uma linha a cada promoção ou arquivamento. Limites: no máximo 3 skills automáticas novas por dia, só no escopo do projeto, e uma consolidação semanal automática que só mexe em skills automáticas.
65
- 1. **Caminho de revisão.** Skills com comandos destrutivos, e mudanças em skills que você aprovou, aparecem em `/skills pending`, sinalizadas quando contêm comandos destrutivos.
66
- 2. `/skills approve <nome>` mostra o **corpo inteiro** e os avisos do lint, e pede confirmação. Essa confirmação é exigida mesmo no modo "tudo liberado".
67
- 3. Skills aprovadas são versionadas (`history/`), ranqueadas por uso e sinalizadas quando os arquivos que citam deixam de existir. `/skills consolidate` junta duplicadas e poda as sem uso.
68
- 4. Uma skill pode ser do projeto ou **global** (vale em todos os projetos); `/skills promote` move uma para global.
69
-
70
- O lint **rejeita** segredos/tokens, caminhos absolutos do usuário, credenciais em URL (`usuario:senha@host`), `curl | sh` e instruções para sobrepor regras ou pular aprovação. Ele **avisa** (sem bloquear) sobre comandos que destroem dados: apagar arquivos de banco ou de dados, `DROP`/`TRUNCATE`, `DELETE` sem `WHERE`, reset de migrações, `git reset --hard`, force push, remoção de volumes do Docker. Uma skill é uma instrução permanente, então um passo que só era seguro no estado de um momento não pode virar o padrão em silêncio.
71
-
72
- ## Instalação
73
-
74
- ### Terminal (`brito-cli`)
75
-
76
- Requer Node >= 20. Desenvolvido no macOS; no Linux deve funcionar, no Windows não foi testado.
77
-
78
- ```bash
79
- # pelo npm (o comando é `brito`)
80
- npm i -g brito-cli
81
-
82
- # ou uma linha
83
- curl -fsSL https://raw.githubusercontent.com/wilsonbrito/brito/main/install.sh | bash
84
-
85
- # ou direto do GitHub
86
- npm i -g github:wilsonbrito/brito
87
-
88
- # ou clonando
89
- git clone https://github.com/wilsonbrito/brito && cd brito
90
- npm install && npm run build && npm link
91
- ```
92
-
93
- Escolha um backend:
94
-
95
- ```bash
96
- export ANTHROPIC_API_KEY=sk-ant-... # API da Anthropic
97
- # ou: instale o Claude Code, rode `claude` e /login — o Brito usa a sua assinatura
98
- ```
99
-
100
- ### App de desktop (executável)
101
-
102
- O mesmo agente numa janela: projetos e sessões numa barra lateral, chat com markdown, chamadas de ferramenta recolhíveis, pedidos de permissão e seletores de modelo, esforço e modo de permissão. Não precisa de Node nem de terminal.
103
-
104
- ![App de desktop do Brito respondendo uma pergunta com o grafo de código](docs/images/desktop-app.png)
105
-
106
- *O app de desktop num projeto pequeno: uma pergunta, uma chamada ao grafo (a linha recolhida "executou 1 comando") e a resposta em tabela. A barra lateral agrupa as sessões por projeto; o rodapé mostra o backend, a pasta, o tamanho do contexto e o custo.*
107
-
108
- Baixe na [página de Releases](https://github.com/wilsonbrito/brito/releases):
109
-
110
- | Sistema | Arquivo |
111
- |---|---|
112
- | macOS | `Brito-<versão>-macos-arm64.dmg` (Apple Silicon) ou `-x64.dmg` (Intel): abra e arraste o Brito para Aplicativos |
113
- | Windows | `Brito-<versão>-windows-x64-setup.exe` |
114
- | Linux | `Brito-<versão>-linux-x64.tar.gz`: extraia e rode `./install.sh` (coloca o Brito no menu de aplicativos) |
115
-
116
- Os pacotes não são assinados com Apple Developer ID nem com certificado do Windows, então o macOS ("desenvolvedor não identificado": botão direito, depois Abrir) e o SmartScreen do Windows avisam na primeira abertura. O macOS é a plataforma mais testada; os pacotes de Windows e Linux saem do CI e foram menos exercitados.
117
-
118
- Como na versão de terminal, ele usa a `ANTHROPIC_API_KEY` se o seu shell a exporta; senão, a sua assinatura do Claude Code (`claude`, depois `/login`). Aberto pelo Finder, o app lê o seu shell de login para encontrá-las.
119
-
120
- Para compilar você mesmo: `npm run desktop` (desenvolvimento), `npm run desktop:app` (macOS: instala `/Applications/Brito.app`) ou `npm run desktop:dmg`.
121
-
122
- ## Começando
123
-
124
- ```bash
125
- cd seu-projeto
126
- brito # abre o REPL
127
- brito "quem chama parseConfig?" # prompt único, sem REPL
128
- brito index # (re)indexa o grafo; ele também se mantém atualizado sozinho
129
- brito query "MATCH (c:Symbol {kind:'component'})-[:CALLS]->(f:Symbol) RETURN c.file, f.name LIMIT 5"
130
- ```
131
-
132
- Um `brito index` real no projeto de exemplo acima:
133
-
134
- ```
135
- OK: 20 arquivos, 66 símbolos, 54 chamadas, 17 imports | +0 ~0 -0 =20 (28ms)
136
- ```
137
-
138
- ![Tela inicial do Brito](docs/images/startup.png)
139
-
140
- ### Dentro do REPL
141
-
142
- | Comando | O que faz |
143
- |---|---|
144
- | `/help` | lista os comandos |
145
- | `/model`, `/effort`, `/reasoning` | escolhem modelo, esforço de raciocínio e thinking (sessão, global ou uma vez) |
146
- | `/fallback` | mostra o modelo principal e o fallback (qwen), e se a troca já aconteceu |
147
- | `/modo` ou `Shift+Tab` | troca o modo de permissão: manual → auto-edições → plano → tudo liberado |
148
- | `/skills` | lista skills · `pending` · `approve <nome>` · `reject <nome>` · `consolidate` · `rm <nome>` · `promote <nome>` |
149
- | `/learn` | extrai skills do último turno agora |
150
- | `/agents`, `/tools`, `/index`, `/context` | inspecionam subagentes, tools, o índice e a janela de contexto |
151
- | `!comando` | roda um comando no shell direto, sem chamar o modelo |
152
- | `/clear`, `/exit` | limpa a conversa, sai |
153
-
154
- ## O que o grafo indexa
155
-
156
- - **Linguagens:** TypeScript/JavaScript (`.ts .tsx .mts .cts .js .jsx .mjs .cjs`), Python (`.py`), linguagens de backend — Java (`.java`), Kotlin (`.kt`), Go (`.go`), Ruby (`.rb`), PHP (`.php`), C# (`.cs`), Rust (`.rs`) — e os componentes `.svelte`, `.vue` e `.astro`. Nos componentes o Brito lê o(s) bloco(s) de script (e o frontmatter do Astro) e registra as chamadas feitas no template a funções que o script declara ou importa; cada componente vira um símbolo `component`.
157
- - **Escopo:** em um repositório git, só o que o git considera parte do projeto (rastreados + novos não ignorados), então o que está no `.gitignore` não entra. Fora do git, ou com `BRITO_INDEX_IGNORED=1`, indexa por glob (ainda sem `node_modules`, `dist`, `build`, `target`, `vendor`, `obj`, `.gradle`, `.venv`, `.brito`).
158
- - **Imports:** relativos e por alias. Resolve `paths`/`baseUrl` do `tsconfig.json`/`jsconfig.json` (seguindo `extends` relativo, como o `.svelte-kit/tsconfig.json`), `imports` do `package.json` (`#interno/*`) e o `$lib` do SvelteKit. A configuração vale por arquivo (a mais próxima), então monorepos funcionam; editar um tsconfig reindexa os arquivos afetados.
159
- - **Linguagens de backend:** o grafo guarda classes/interfaces/structs/traits/enums/módulos, funções e métodos (`Classe.metodo`), chamadas e imports. Nelas o import nomeia um pacote, não um caminho; o Brito casa o especificador com o final do caminho dos seus arquivos (`com.acme.Repo` ↔ `src/main/java/com/acme/Repo.java`; namespaces PSR-4 do PHP; `use crate::…` do Rust; `require`/`require_relative` do Ruby; pacotes Go pelo módulo do `go.mod`). Pacote externo (`java.util`, `serde`, `github.com/gin-gonic/gin`) nunca casa e não gera aresta. Não há inferência de tipos: `userRepository.save()` é ligado casando o nome do receptor com um tipo do projeto (`UserRepository`), `this`/`self`/receiver resolvem para a classe que contém a chamada, e uma chamada solta dentro de classe tenta primeiro os métodos da própria classe.
160
- - **Ainda não:** `extends` por pacote (`@tsconfig/node20`), `exports` de workspaces vizinhos e referências de função sem chamada em um template (`onclick={fn}`). As chamadas são resolvidas estaticamente, com fallback por nome, então despacho dinâmico e reflexão não são capturados.
161
-
162
- ## Bancos de dados e outros recursos sensíveis
163
-
164
- O Brito **não tem drivers de banco e não se conecta a nada sozinho**. Quando precisa mexer em um banco, usa as ferramentas do próprio projeto pelo shell, sob o modo de permissão que você escolheu. Como cada projeto é diferente (um arquivo local, um servidor remoto, um container), declare as partes sensíveis no `BRITO.md` (ou `CLAUDE.md` / `AGENTS.md`), que é lido para o system prompt:
165
-
166
- ```markdown
167
- ## Recursos protegidos
168
- - Banco: arquivo SQLite local `local.db` (nunca commitar, nunca recriar).
169
- Teste mudanças destrutivas numa cópia: `cp local.db /tmp/teste.db` e aponte `DATABASE_URL`.
170
- Mudanças de schema: só aditivas, com backup antes (`cp local.db backups/pre-mudanca.db`).
171
- - Postgres de staging: a connection string está em `$STAGING_DATABASE_URL` (papel somente leitura). Nunca toque em produção.
172
- ```
173
-
174
- - Credenciais nunca pertencem a skills ou notas: o lint as rejeita. Cite o **nome** da variável de ambiente.
175
- - Prefira papéis somente leitura e ambientes que não sejam de produção ao dar acesso a banco para um agente.
176
- - Uma skill proposta que contém comando destrutivo é destacada na revisão, para você decidir se precisa de uma guarda (backup, cópia, confirmação).
177
-
178
- ## Endpoint compatível com OpenAI (ex.: Qwen no OCI)
179
-
180
- > Passo a passo completo (instalação, chave, perfil e como dar acesso ao repositório): [docs/GUIA-QWEN.md](docs/GUIA-QWEN.md).
181
-
182
- Além do Claude, o Brito roda com qualquer modelo servido pela API **Chat Completions** da OpenAI (vLLM, OCI Generative AI, LiteLLM, Ollama…) com chamada de ferramentas. Cadastre um perfil em `~/.brito/config.json`:
183
-
184
- ```json
185
- {
186
- "providers": {
187
- "qwen": {
188
- "type": "openai",
189
- "label": "Qwen 27B (OCI)",
190
- "baseURL": "https://inference.generativeai.<região>.oci.oraclecloud.com/openai/v1",
191
- "model": "<id do modelo; no OCI, o OCID do endpoint dedicado>",
192
- "apiKeyEnv": "BRITO_QWEN_API_KEY",
193
- "contextWindow": 262144,
194
- "vision": false,
195
- "thinkingToggle": true
196
- }
197
- }
198
- }
199
- ```
200
-
201
- A chave **não** fica no config: ponha na variável de ambiente indicada em `apiKeyEnv`. Depois:
202
-
203
- ```bash
204
- brito --model qwen # esta sessão
205
- /model qwen --global # dentro do REPL: vira o padrão
206
- ```
207
-
208
- Com um perfil escolhido, **tudo** vai para o endpoint: agente principal, subagentes (o `explore` deixa de usar o Haiku), resumo de contexto e aprendizado de skills; o Brito abre sem `ANTHROPIC_API_KEY` e sem o `claude` CLI. `/reasoning none` desliga o raciocínio do modelo (respostas bem mais rápidas no Qwen). `thinkingToggle: true` só para servidores que aceitam `chat_template_kwargs` (vLLM/Qwen); sem ele o `/reasoning none` não tem efeito, mas nenhum parâmetro estranho é enviado. Imagens só são enviadas com `"vision": true`. Exceção consciente: `BRITO_EXPLORE_MODEL` continua mandando no subagente `explore`; já um `BRITO_LEARN_MODEL` que aponte para um Claude é ignorado enquanto um perfil estiver ativo. Perfil com erro no config não cai no Claude: o Brito avisa e para. `/effort` continua exclusivo do modo `claude` CLI, e um perfil não roda dentro do `claude` CLI (o `/model` avisa para reabrir com `--model`).
209
-
210
- ### Fallback para o Qwen
211
-
212
- Com o Claude como modelo principal (API ou `claude` CLI), o perfil `qwen` é o fallback automático — sempre ele, sem chave nova no config. Se o Claude falha por **limite da assinatura, rate limit, crédito, autenticação, sobrecarga ou rede**, o Brito avisa e refaz o pedido no Qwen com a conversa até ali (as tools que já rodaram ficam no histórico, para não serem repetidas). No modo `claude` CLI o motor inteiro troca para o loop próprio do Brito.
213
-
214
- - A troca acontece uma vez por sessão e não volta sozinha: `/model <claude>` volta ao Claude (e o fallback pode disparar de novo depois).
215
- - Não troca por Ctrl+C nem por erro de conteúdo (requisição inválida, `max_tokens`, tool quebrada).
216
- - Sem `ANTHROPIC_API_KEY` e sem o `claude` CLI, o Brito já abre no Qwen, com aviso. Sem o fallback pronto, o erro de sempre inclui o motivo (ex.: falta `BRITO_QWEN_API_KEY`). Perfil `qwen` inválido continua sendo erro, nunca fallback silencioso.
217
- - `/fallback` mostra o estado. No app de desktop, envie `/fallback` como mensagem; a barra de status mostra o Qwen quando o fallback está ativo.
218
-
219
- ```
220
- /fallback
221
- principal claude-opus-5-5 (claude CLI · assinatura)
222
- fallback Qwen 27B (OCI) qwen · ~/.brito/config.json ✓ pronto
223
- estado inativo — troca automática se o Claude falhar por limite, crédito, auth ou sobrecarga
224
- ```
225
-
226
- ## Configuração
227
-
228
- `BRITO_MODEL`, `BRITO_EFFORT`, `BRITO_EXPLORE_MODEL`, `BRITO_LEARN_MODEL`, `BRITO_HOME` (onde ficam skills globais e histórico), `BRITO_CONFIG`, `BRITO_COLOR`, `BRITO_BANNER` (`compact` ou `full`; padrão: tela cheia em janelas de 95+ colunas e 28+ linhas), `BRITO_INDEX_IGNORED`, `BRITO_SKILL_MIN_TOOLS` (tamanho mínimo do turno para disparar a reflexão quando nada mais dispara), `BRITO_SKILLS` (`auto` padrão, `ask`, `off`), `BRITO_SHELL` (shell da tool `bash`; no Windows usa o Git Bash se instalado).
229
-
230
- Os dados do projeto ficam em `.brito/` (grafo, skills do projeto, agentes) e os globais em `~/.brito`. O grafo, a memória e as skills ficam na sua máquina; como em qualquer agente de código, o código que o modelo lê é enviado ao provedor de modelo que você configurou.
231
-
232
- ## Limitações
233
-
234
- - Software em fase inicial (v0.5.0), um mantenedor.
235
- - O app de desktop é novo: uma janela só (sem abas ainda) e, com chave de API (sem o `claude` CLI), o modelo não retoma a conversa ao reabrir o app, embora a tela a mostre.
236
- - **A interface e o idioma padrão do agente são português do Brasil.** Traduzi-los é uma contribuição bem-vinda.
237
- - O aprendizado de skills é heurístico: ele propõe, você decide. Espere rejeitar algumas propostas.
238
-
239
- ## Desenvolvimento
240
-
241
- ```bash
242
- git clone https://github.com/wilsonbrito/brito && cd brito
243
- npm install
244
- npm run dev # roda via tsx
245
- npm run typecheck
246
- npm test # 190+ testes, incluindo um servidor MCP real e um REPL real
247
- ```
248
-
249
- | Caminho | O quê |
250
- |---|---|
251
- | `src/graph/` | indexador (tree-sitter), suporte a `.svelte/.vue/.astro`, aliases de import, store Ladybug (Kùzu) |
252
- | `src/skills/` | store, lint, reflexão, journal, consolidação |
253
- | `src/agent/` | loop do agente, prompts, subagentes, backend da CLI `claude` |
254
- | `src/tools/` | tools de grafo, memória, skills, arquivos e shell |
255
- | `src/mcp/` | servidor MCP |
256
- | `src/repl.ts`, `src/ui/` | interface de terminal |
257
- | `src/desktop/` | `brito gui-serve`: o backend com que a janela do desktop conversa (JSON por stdio) |
258
- | `desktop/` | janela Electron e empacotamento (`package.mjs`); `npm run bundle` gera o backend em arquivo único que ela usa |
259
-
260
- ## Licença
261
-
262
- [PolyForm Noncommercial 1.0.0](LICENSE): uso, estudo e modificação livres para qualquer fim não comercial (uso pessoal, pesquisa, educação, hobby, ONGs). Uso comercial não é permitido. É código disponível (source-available), não open source pela definição da OSI. Precisa de licença comercial? Abra uma issue.
1
+ # Brito
2
+
3
+ [English](README.md) · **Português**
4
+
5
+ > Um agente de código para o seu terminal (`brito-cli`) e para o seu desktop (um app nativo) que conhece o seu projeto como um **grafo** e aprende os procedimentos dele como **skills que você revisa**.
6
+
7
+ O Brito é um agente para desenvolvimento de software. Use no terminal (`brito-cli` no npm) ou como app de desktop (um executável para macOS, Windows e Linux): o mesmo agente, o mesmo grafo, as mesmas skills. Em vez de dar `grep` e ler arquivos às cegas, ele mantém um **grafo de conhecimento do código** (símbolos, quem chama quem, quem importa quem) e responde perguntas como *"o que quebra se eu mudar isto?"* direto do grafo, em uma fração de segundo. Ele também guarda **notas de memória** e **skills**: procedimentos reutilizáveis aprendidos no seu próprio trabalho, que só passam a valer depois que **você** aprova.
8
+
9
+ ![Brito respondendo uma pergunta com o grafo de código](docs/images/answer-with-graph.png)
10
+
11
+ *Uma sessão real num pequeno projeto SvelteKit: uma pergunta, duas consultas ao grafo (0,1 s e 0,0 s) e uma resposta que já inclui os componentes `.svelte` que dependem do arquivo. A barra de status mostra o custo real do turno.*
12
+
13
+ ## Destaques
14
+
15
+ > **Atualizando para a 0.6:** o motor do grafo mudou do Kùzu (descontinuado) para o LadybugDB. O grafo é reconstruído sozinho no primeiro uso; o seu `.brito/graph.kuzu` antigo é mantido. O Brito pergunta uma vez se copia as suas notas (memória) para o grafo novo, ou rode `brito migrar-notas` quando quiser. Os testes rodam no CI em macOS, Linux e Windows (use a 0.6.1 ou posterior no Windows/Linux). Veja o [CHANGELOG](CHANGELOG.md).
16
+
17
+ - **Exploração guiada pelo grafo.** `graph_search`, `graph_context`, `graph_callers`, `graph_callees` e `graph_impact` respondem "onde está, quem usa, o que quebra" sem ler arquivos inteiros. O grafo é embutido ([LadybugDB](https://github.com/LadybugDB/ladybug), fork mantido do Kùzu), local e incremental.
18
+ - **Cobertura ampla.** TypeScript/JavaScript, Python e os blocos de script de componentes `.svelte`, `.vue` e `.astro`. Aliases de import (`paths` do tsconfig, `imports` do package.json, `$lib` do SvelteKit) viram arestas de verdade. O que o `.gitignore` ignora fica de fora.
19
+ - **Skills que aprendem sozinhas, em período de teste.** Depois de uma tarefa em que algo tropeçou ou foi corrigido, o Brito reflete e cria uma skill *em teste* sem te interromper. A skill se prova pelo uso: 3 usos limpos a promovem, 2 tropeços a arquivam (recuperável). O que é arriscado, ou qualquer mudança numa skill que você aprovou, continua esperando o seu `/skills approve`. `BRITO_SKILLS=ask` volta a pedir aprovação para tudo; `off` desliga o aprendizado.
20
+ - **Proteções sobre o que é aprendido.** Um lint rejeita segredos, credenciais embutidas em URL, `curl | sh` e frases de injeção de prompt, e **avisa sobre comandos destrutivos** (veja abaixo).
21
+ - **Modos e regras de permissão.** manual, auto-edições, plano e "tudo liberado" (`Shift+Tab` alterna), mais regras `allow`/`deny` por comando ou caminho (veja [Regras de permissão](#regras-de-permissão)). Editar um arquivo exige tê-lo lido na sessão, sem mudanças desde então. As skills autônomas não dependem do modo: nascem em teste e são julgadas pelo resultado.
22
+ - **Dois backends, uma interface.** Use uma chave da API da Anthropic ou a sua assinatura do Claude Code pela CLI `claude`. O Brito nunca lê nem envia o token da sua assinatura.
23
+ - **Terminal ou app de desktop.** `npm i -g brito-cli` instala o comando `brito`; o app de desktop é um executável nativo com janela (projetos e sessões numa barra lateral, chat, pedidos de permissão), sem precisar de Node nem de terminal. Veja [Instalação](#instalação).
24
+ - **Imagens.** Arraste um arquivo de imagem para o prompt (ou cole o caminho) e ele é anexado ao turno: PNG, JPEG, GIF ou WebP, até 5 MB.
25
+ - **Subagentes.** `explore`, `plan` e `general` rodam em contextos isolados (os somente-leitura, em paralelo); crie os seus em `.brito/agents/*.md`.
26
+ - **Servidor MCP.** `brito mcp-serve` expõe grafo, memória e skills a outros clientes MCP, como o Claude Code. As tools de consulta são marcadas `alwaysLoad`, para não ficarem escondidas atrás da busca de tools.
27
+
28
+ ## Como funciona
29
+
30
+ ![Indexação uma vez, depois respostas vindas do grafo em vez de grep e leitura de arquivos](docs/images/graph-vs-grep.pt-BR.svg)
31
+
32
+ *O grafo é construído uma vez e atualizado de forma incremental; uma pergunta como "o que quebra se eu mudar isto?" vira uma ou duas chamadas ao grafo.*
33
+
34
+ ```mermaid
35
+ flowchart LR
36
+ code["Seu projeto<br/>.ts · .js · .py · .java · .kt · .go · .rb · .php · .cs · .rs · .svelte · .vue · .astro"] -->|"tree-sitter<br/>incremental"| cg[("Grafo de código<br/>símbolos · chamadas · imports")]
37
+ cg <-->|"graph_search · graph_callers<br/>graph_impact · graph_context"| agent{{"Agente Brito"}}
38
+ mem[("Memória<br/>decisões · convenções")] <-->|"recall / remember"| agent
39
+ agent -->|"após uma tarefa complexa"| learn["Reflexão"]
40
+ learn -->|"propõe"| pending["Skills pendentes"]
41
+ pending -->|"/skills approve<br/>você decide"| skills[("Skills<br/>.brito/skills")]
42
+ skills -->|"skill_load"| agent
43
+ ```
44
+
45
+ - **Grafo de código**: funções, classes, métodos e componentes como nós; `CALLS` e `IMPORTS` como arestas. Só reparseia os arquivos cujo hash mudou e se atualiza sozinho após edições.
46
+ - **Memória**: notas duráveis (decisões, convenções, bugs descobertos) ligadas a arquivos e símbolos, recuperadas com `recall`.
47
+ - **Skills**: procedimentos passo a passo para o *seu* projeto (comandos, ordem, armadilhas, como verificar). O agente carrega uma com `skill_load` antes de uma tarefa que ela cobre.
48
+ - **Journal**: o Brito lembra entre sessões quais tarefas se repetiram, o melhor indício de que um procedimento é geral e vale guardar.
49
+
50
+ ### Arquitetura em uma imagem
51
+
52
+ ![Arquitetura do Brito: contexto, permissões, ferramentas e subagentes ao redor do modelo](docs/images/architecture.pt-BR.svg)
53
+
54
+ *Tudo o que o modelo vê ou pode fazer é um dos oito componentes, agrupados por papel. O texto em monoespaçado é o arquivo ou comando real; a etiqueta diz quando ele entra em ação.*
55
+
56
+ ## Skills que merecem o lugar
57
+
58
+ ![Ciclo de vida da skill: tarefa, reflexão, teste ou pendente, ativa ou arquivada](docs/images/skill-lifecycle.pt-BR.svg)
59
+
60
+ *Os dois caminhos de uma skill. As seguras se provam em teste; as arriscadas esperam a sua aprovação.*
61
+
62
+ ![Revisando uma skill pendente, com aviso de comando destrutivo](docs/images/skills-review.png)
63
+
64
+ 0. **Caminho autônomo (padrão).** A reflexão grava a skill nova como *em teste*, marcada "(em teste)" no índice. Cada turno que a carrega conta como vitória (sem erro→conserto nem correção do usuário) ou falha. 3 vitórias (e no máximo 1 falha a cada 3 vitórias) a promovem; 2 falhas sem mais vitórias, ou 21 dias sem uso, a arquivam em `.brito/skills/.trash`. O Brito imprime uma linha a cada promoção ou arquivamento. Limites: no máximo 3 skills automáticas novas por dia, só no escopo do projeto, e uma consolidação semanal automática que só mexe em skills automáticas.
65
+ 1. **Caminho de revisão.** Skills com comandos destrutivos, e mudanças em skills que você aprovou, aparecem em `/skills pending`, sinalizadas quando contêm comandos destrutivos.
66
+ 2. `/skills approve <nome>` mostra o **corpo inteiro** e os avisos do lint, e pede confirmação. Essa confirmação é exigida mesmo no modo "tudo liberado".
67
+ 3. Skills aprovadas são versionadas (`history/`), ranqueadas por uso e sinalizadas quando os arquivos que citam deixam de existir. `/skills consolidate` junta duplicadas e poda as sem uso.
68
+ 4. Uma skill pode ser do projeto ou **global** (vale em todos os projetos); `/skills promote` move uma para global.
69
+
70
+ O lint **rejeita** segredos/tokens, caminhos absolutos do usuário, credenciais em URL (`usuario:senha@host`), `curl | sh` e instruções para sobrepor regras ou pular aprovação. Ele **avisa** (sem bloquear) sobre comandos que destroem dados: apagar arquivos de banco ou de dados, `DROP`/`TRUNCATE`, `DELETE` sem `WHERE`, reset de migrações, `git reset --hard`, force push, remoção de volumes do Docker. Uma skill é uma instrução permanente, então um passo que só era seguro no estado de um momento não pode virar o padrão em silêncio.
71
+
72
+ ## Modelo local (opcional)
73
+
74
+ `brito slm pull` baixa um modelo local pequeno (Qwen3-4B-Instruct-2507 Q4_K_M, Apache-2.0) para `~/.brito/models`, pela dependência opcional `node-llama-cpp`. `brito slm` mostra o status e `brito slm rm` o apaga. Depois de baixado, ele é usado em:
75
+
76
+ - **Aprendizado de skills**: a reflexão roda localmente com JSON restrito por gramática e cai no modelo de sempre se algo falhar.
77
+ - **Tool `digest`**: batedor e refinador de textos longos. O modelo local escolhe os blocos mais ligados ao seu objetivo e propõe trechos; o código confere cada citação contra a fonte e descarta o que não existe, e o modelo principal recebe um rascunho pequeno em markdown com citações verificadas e números de página.
78
+
79
+ - **Fallback quando o Claude acaba**: cadeia Claude → perfil `qwen` → SLM local, com o loop completo do agente e as tools (mesmas permissões). É temporário: passada a janela (o horário de reset que o erro informa, senão 10 min, ou 60 min para cota/auth; `BRITO_FALLBACK_MINUTES` sobrepõe) o próximo turno tenta o Claude de novo. O `/fallback` mostra quando. Um modelo de 4B erra mais com tools: use para continuar, não para tarefas grandes. `BRITO_SLM_FALLBACK=off` tira o SLM da cadeia; `BRITO_SLM_CTX` define o contexto.
80
+
81
+ `BRITO_SLM=off` desliga; `BRITO_SLM_MODEL` aponta para outro GGUF (URI `hf:` ou caminho de arquivo).
82
+
83
+ ## Instalação
84
+
85
+ ### Terminal (`brito-cli`)
86
+
87
+ Requer Node >= 20. Desenvolvido no macOS; no Linux deve funcionar, no Windows não foi testado.
88
+
89
+ ```bash
90
+ # pelo npm (o comando é `brito`)
91
+ npm i -g brito-cli
92
+
93
+ # ou uma linha
94
+ curl -fsSL https://raw.githubusercontent.com/wilsonbrito/brito/main/install.sh | bash
95
+
96
+ # ou direto do GitHub
97
+ npm i -g github:wilsonbrito/brito
98
+
99
+ # ou clonando
100
+ git clone https://github.com/wilsonbrito/brito && cd brito
101
+ npm install && npm run build && npm link
102
+ ```
103
+
104
+ Escolha um backend:
105
+
106
+ ```bash
107
+ export ANTHROPIC_API_KEY=sk-ant-... # API da Anthropic
108
+ # ou: instale o Claude Code, rode `claude` e /login — o Brito usa a sua assinatura
109
+ ```
110
+
111
+ ### App de desktop (executável)
112
+
113
+ O mesmo agente numa janela: projetos e sessões numa barra lateral, chat com markdown, chamadas de ferramenta recolhíveis, pedidos de permissão e seletores de modelo, esforço e modo de permissão. Não precisa de Node nem de terminal.
114
+
115
+ ![App de desktop do Brito respondendo uma pergunta com o grafo de código](docs/images/desktop-app.png)
116
+
117
+ *O app de desktop num projeto pequeno: uma pergunta, uma chamada ao grafo (a linha recolhida "executou 1 comando") e a resposta em tabela. A barra lateral agrupa as sessões por projeto; o rodapé mostra o backend, a pasta, o tamanho do contexto e o custo.*
118
+
119
+ Baixe na [página de Releases](https://github.com/wilsonbrito/brito/releases):
120
+
121
+ | Sistema | Arquivo |
122
+ |---|---|
123
+ | macOS | `Brito-<versão>-macos-arm64.dmg` (Apple Silicon) ou `-x64.dmg` (Intel): abra e arraste o Brito para Aplicativos |
124
+ | Windows | `Brito-<versão>-windows-x64-setup.exe` |
125
+ | Linux | `Brito-<versão>-linux-x64.tar.gz`: extraia e rode `./install.sh` (coloca o Brito no menu de aplicativos) |
126
+
127
+ Os pacotes não são assinados com Apple Developer ID nem com certificado do Windows, então o macOS ("desenvolvedor não identificado": botão direito, depois Abrir) e o SmartScreen do Windows avisam na primeira abertura. O macOS é a plataforma mais testada; os pacotes de Windows e Linux saem do CI e foram menos exercitados.
128
+
129
+ Como na versão de terminal, ele usa a `ANTHROPIC_API_KEY` se o seu shell a exporta; senão, a sua assinatura do Claude Code (`claude`, depois `/login`). Aberto pelo Finder, o app lê o seu shell de login para encontrá-las.
130
+
131
+ Para compilar você mesmo: `npm run desktop` (desenvolvimento), `npm run desktop:app` (macOS: instala `/Applications/Brito.app`) ou `npm run desktop:dmg`.
132
+
133
+ ## Começando
134
+
135
+ ```bash
136
+ cd seu-projeto
137
+ brito # abre o REPL
138
+ brito "quem chama parseConfig?" # prompt único, sem REPL
139
+ brito index # (re)indexa o grafo; ele também se mantém atualizado sozinho
140
+ brito -c # retoma a sessão mais recente deste projeto
141
+ brito sessoes # lista as sessões salvas; retome uma com brito --resume <id>
142
+ brito slm pull # (opcional) baixa o modelo local usado por digest e pelo aprendizado de skills
143
+ brito query "MATCH (c:Symbol {kind:'component'})-[:CALLS]->(f:Symbol) RETURN c.file, f.name LIMIT 5"
144
+ ```
145
+
146
+ Um `brito index` real no projeto de exemplo acima:
147
+
148
+ ```
149
+ OK: 20 arquivos, 66 símbolos, 54 chamadas, 17 imports | +0 ~0 -0 =20 (28ms)
150
+ ```
151
+
152
+ ![Tela inicial do Brito](docs/images/startup.png)
153
+
154
+ ### Dentro do REPL
155
+
156
+ | Comando | O que faz |
157
+ |---|---|
158
+ | `/help` | lista os comandos |
159
+ | `/model`, `/effort`, `/reasoning` | escolhem modelo, esforço de raciocínio e thinking (sessão, global ou uma vez) |
160
+ | `/fallback` | mostra o modelo principal e o fallback (qwen), e se a troca já aconteceu |
161
+ | `/modo` ou `Shift+Tab` | troca o modo de permissão: manual → auto-edições → plano → tudo liberado |
162
+ | `/skills` | lista skills · `pending` · `approve <nome>` · `reject <nome>` · `consolidate` · `rm <nome>` · `promote <nome>` |
163
+ | `/permissions` | lista as regras de permissão · `allow <regra>` · `deny <regra>` |
164
+ | `/learn` | extrai skills do último turno agora |
165
+ | `/grill-me`, `/grill-with-docs`, `/wayfinder`, `/grill-diff` | skills manuais embutidas: entrevista até a ideia ficar firme (`--um` = uma pergunta por mensagem), também grava decisões com `remember`, mapeia trabalho grande e delega, questiona o diff atual |
166
+ | `/skills suggest <tarefa>` | ranqueia as skills (embutidas inclusive) por relevância para a tarefa |
167
+ | `/agents`, `/tools`, `/index`, `/context` | inspecionam subagentes, tools, o índice e a janela de contexto |
168
+ | `!comando` | roda um comando no shell direto, sem chamar o modelo |
169
+ | `/todos` | mostra a lista de tarefas da sessão (o agente a mantém com `todo_write` em tarefas de vários passos) |
170
+ | `/sessions` | lista as sessões salvas deste projeto |
171
+ | `/clear`, `/exit` | começa outra conversa (a anterior continua salva), sai |
172
+
173
+ ## O que o grafo indexa
174
+
175
+ - **Linguagens:** TypeScript/JavaScript (`.ts .tsx .mts .cts .js .jsx .mjs .cjs`), Python (`.py`), linguagens de backend — Java (`.java`), Kotlin (`.kt`), Go (`.go`), Ruby (`.rb`), PHP (`.php`), C# (`.cs`), Rust (`.rs`) — e os componentes `.svelte`, `.vue` e `.astro`. Nos componentes o Brito lê o(s) bloco(s) de script (e o frontmatter do Astro) e registra as chamadas feitas no template a funções que o script declara ou importa; cada componente vira um símbolo `component`.
176
+ - **Escopo:** em um repositório git, só o que o git considera parte do projeto (rastreados + novos não ignorados), então o que está no `.gitignore` não entra. Fora do git, ou com `BRITO_INDEX_IGNORED=1`, indexa por glob (ainda sem `node_modules`, `dist`, `build`, `target`, `vendor`, `obj`, `.gradle`, `.venv`, `.brito`).
177
+ - **Imports:** relativos e por alias. Resolve `paths`/`baseUrl` do `tsconfig.json`/`jsconfig.json` (seguindo `extends` relativo, como o `.svelte-kit/tsconfig.json`), `imports` do `package.json` (`#interno/*`) e o `$lib` do SvelteKit. A configuração vale por arquivo (a mais próxima), então monorepos funcionam; editar um tsconfig reindexa os arquivos afetados.
178
+ - **Linguagens de backend:** o grafo guarda classes/interfaces/structs/traits/enums/módulos, funções e métodos (`Classe.metodo`), chamadas e imports. Nelas o import nomeia um pacote, não um caminho; o Brito casa o especificador com o final do caminho dos seus arquivos (`com.acme.Repo` ↔ `src/main/java/com/acme/Repo.java`; namespaces PSR-4 do PHP; `use crate::…` do Rust; `require`/`require_relative` do Ruby; pacotes Go pelo módulo do `go.mod`). Pacote externo (`java.util`, `serde`, `github.com/gin-gonic/gin`) nunca casa e não gera aresta. Não há inferência de tipos: `userRepository.save()` é ligado casando o nome do receptor com um tipo do projeto (`UserRepository`), `this`/`self`/receiver resolvem para a classe que contém a chamada, e uma chamada solta dentro de classe tenta primeiro os métodos da própria classe.
179
+ - **Ainda não:** `extends` por pacote (`@tsconfig/node20`), `exports` de workspaces vizinhos e referências de função sem chamada em um template (`onclick={fn}`). As chamadas são resolvidas estaticamente, com fallback por nome, então despacho dinâmico e reflexão não são capturados.
180
+
181
+ ## Regras de permissão
182
+
183
+ Para não aprovar o mesmo comando toda vez (nem precisar do "tudo liberado"), declare regras em `.brito/settings.json` (do projeto, pode ir para o git), `.brito/settings.local.json` (só seu) ou `~/.brito/settings.json` (todos os projetos). As listas se somam.
184
+
185
+ ```json
186
+ {
187
+ "permissions": {
188
+ "allow": ["bash(npm test:*)", "bash(npm run typecheck)", "bash(git status:*)", "edit_file(src/**)"],
189
+ "deny": ["bash(git push:*)", "bash(rm -rf*)", "read_file(.env*)"]
190
+ }
191
+ }
192
+ ```
193
+
194
+ - `tool` vale para qualquer uso; `tool(padrão)` restringe. Em `bash`, `*` casa qualquer coisa e `:*` no fim casa o prefixo sozinho ou com argumentos (`git status:*` libera `git status --short`, não `git statusx`). Em caminhos, `*` não cruza diretórios e `**` cruza.
195
+ - **`allow` dispensa a pergunta** nos modos manual e auto-edições. O modo plano continua bloqueando.
196
+ - **`deny` bloqueia sempre**, inclusive no "tudo liberado".
197
+ - Um comando composto só é liberado se **cada pedaço** (`&&`, `||`, `;`, `|`) casar com uma regra: `bash(npm test*)` não libera `npm test && rm -rf ~`. Comandos com `$(...)`, crases ou redirecionamento para arquivo nunca são liberados por regra; `2>&1` e `> /dev/null` podem.
198
+ - As regras valem também para o Bash, o Edit e o Write do `claude` CLI quando o Brito roda sobre a sua assinatura.
199
+ - `/permissions` lista as regras; `/permissions allow bash(npm test:*)` grava no `.brito/settings.json`.
200
+
201
+ ## Bancos de dados e outros recursos sensíveis
202
+
203
+ O Brito **não tem drivers de banco e não se conecta a nada sozinho**. Quando precisa mexer em um banco, usa as ferramentas do próprio projeto pelo shell, sob o modo de permissão que você escolheu. Como cada projeto é diferente (um arquivo local, um servidor remoto, um container), declare as partes sensíveis no `BRITO.md` (ou `CLAUDE.md` / `AGENTS.md`), que é lido para o system prompt:
204
+
205
+ ```markdown
206
+ ## Recursos protegidos
207
+ - Banco: arquivo SQLite local `local.db` (nunca commitar, nunca recriar).
208
+ Teste mudanças destrutivas numa cópia: `cp local.db /tmp/teste.db` e aponte `DATABASE_URL`.
209
+ Mudanças de schema: só aditivas, com backup antes (`cp local.db backups/pre-mudanca.db`).
210
+ - Postgres de staging: a connection string está em `$STAGING_DATABASE_URL` (papel somente leitura). Nunca toque em produção.
211
+ ```
212
+
213
+ - Credenciais nunca pertencem a skills ou notas: o lint as rejeita. Cite o **nome** da variável de ambiente.
214
+ - Prefira papéis somente leitura e ambientes que não sejam de produção ao dar acesso a banco para um agente.
215
+ - Uma skill proposta que contém comando destrutivo é destacada na revisão, para você decidir se precisa de uma guarda (backup, cópia, confirmação).
216
+
217
+ ## Endpoint compatível com OpenAI (ex.: Qwen no OCI)
218
+
219
+ > Passo a passo completo (instalação, chave, perfil e como dar acesso ao repositório): [docs/GUIA-QWEN.md](docs/GUIA-QWEN.md).
220
+
221
+ Além do Claude, o Brito roda com qualquer modelo servido pela API **Chat Completions** da OpenAI (vLLM, OCI Generative AI, LiteLLM, Ollama…) com chamada de ferramentas. Cadastre um perfil em `~/.brito/config.json`:
222
+
223
+ ```json
224
+ {
225
+ "providers": {
226
+ "qwen": {
227
+ "type": "openai",
228
+ "label": "Qwen 27B (OCI)",
229
+ "baseURL": "https://inference.generativeai.<região>.oci.oraclecloud.com/openai/v1",
230
+ "model": "<id do modelo; no OCI, o OCID do endpoint dedicado>",
231
+ "apiKeyEnv": "BRITO_QWEN_API_KEY",
232
+ "contextWindow": 262144,
233
+ "vision": false,
234
+ "thinkingToggle": true
235
+ }
236
+ }
237
+ }
238
+ ```
239
+
240
+ A chave **não** fica no config: ponha na variável de ambiente indicada em `apiKeyEnv`. Depois:
241
+
242
+ ```bash
243
+ brito --model qwen # esta sessão
244
+ /model qwen --global # dentro do REPL: vira o padrão
245
+ ```
246
+
247
+ Com um perfil escolhido, **tudo** vai para o endpoint: agente principal, subagentes (o `explore` deixa de usar o Haiku), resumo de contexto e aprendizado de skills; o Brito abre sem `ANTHROPIC_API_KEY` e sem o `claude` CLI. `/reasoning none` desliga o raciocínio do modelo (respostas bem mais rápidas no Qwen). `thinkingToggle: true` só para servidores que aceitam `chat_template_kwargs` (vLLM/Qwen); sem ele o `/reasoning none` não tem efeito, mas nenhum parâmetro estranho é enviado. Imagens só são enviadas com `"vision": true`. Exceção consciente: `BRITO_EXPLORE_MODEL` continua mandando no subagente `explore`; já um `BRITO_LEARN_MODEL` que aponte para um Claude é ignorado enquanto um perfil estiver ativo. Perfil com erro no config não cai no Claude: o Brito avisa e para. `/effort` continua exclusivo do modo `claude` CLI, e um perfil não roda dentro do `claude` CLI (o `/model` avisa para reabrir com `--model`).
248
+
249
+ ### Fallback para o Qwen
250
+
251
+ Com o Claude como modelo principal (API ou `claude` CLI), o perfil `qwen` é o fallback automático — sempre ele, sem chave nova no config. Se o Claude falha por **limite da assinatura, rate limit, crédito, autenticação, sobrecarga ou rede**, o Brito avisa e refaz o pedido no Qwen com a conversa até ali (as tools que já rodaram ficam no histórico, para não serem repetidas). No modo `claude` CLI o motor inteiro troca para o loop próprio do Brito.
252
+
253
+ - A troca acontece uma vez por sessão e não volta sozinha: `/model <claude>` volta ao Claude (e o fallback pode disparar de novo depois).
254
+ - Não troca por Ctrl+C nem por erro de conteúdo (requisição inválida, `max_tokens`, tool quebrada).
255
+ - Sem `ANTHROPIC_API_KEY` e sem o `claude` CLI, o Brito já abre no Qwen, com aviso. Sem o fallback pronto, o erro de sempre inclui o motivo (ex.: falta `BRITO_QWEN_API_KEY`). Perfil `qwen` inválido continua sendo erro, nunca fallback silencioso.
256
+ - `/fallback` mostra o estado. No app de desktop, envie `/fallback` como mensagem; a barra de status mostra o Qwen quando o fallback está ativo.
257
+
258
+ ```
259
+ /fallback
260
+ principal claude-opus-5-5 (claude CLI · assinatura)
261
+ fallback Qwen 27B (OCI) qwen · ~/.brito/config.json ✓ pronto
262
+ estado inativo — troca automática se o Claude falhar por limite, crédito, auth ou sobrecarga
263
+ ```
264
+
265
+ ## Configuração
266
+
267
+ `BRITO_MODEL`, `BRITO_EFFORT`, `BRITO_EXPLORE_MODEL`, `BRITO_LEARN_MODEL`, `BRITO_HOME` (onde ficam skills globais e histórico), `BRITO_CONFIG`, `BRITO_COLOR`, `BRITO_BANNER` (`compact` ou `full`; padrão: tela cheia em janelas de 95+ colunas e 28+ linhas), `BRITO_INDEX_IGNORED`, `BRITO_SKILL_MIN_TOOLS` (tamanho mínimo do turno para disparar a reflexão quando nada mais dispara), `BRITO_SKILLS` (`auto` padrão, `ask`, `off`), `BRITO_SHELL` (shell da tool `bash`; no Windows usa o Git Bash se instalado).
268
+
269
+ Os dados do projeto ficam em `.brito/` (grafo, skills do projeto, agentes) e os globais em `~/.brito`. O grafo, a memória e as skills ficam na sua máquina; como em qualquer agente de código, o código que o modelo lê é enviado ao provedor de modelo que você configurou.
270
+
271
+ ## Limitações
272
+
273
+ - Software em fase inicial (v0.5.0), um mantenedor.
274
+ - O app de desktop é novo: uma janela só (sem abas ainda). Conversas do modo API feitas antes desta versão não são retomadas ao reabrir o app (as novas são, a partir de `.brito/sessions`).
275
+ - **A interface e o idioma padrão do agente são português do Brasil.** Traduzi-los é uma contribuição bem-vinda.
276
+ - O aprendizado de skills é heurístico: ele propõe, você decide. Espere rejeitar algumas propostas.
277
+
278
+ ## Desenvolvimento
279
+
280
+ ```bash
281
+ git clone https://github.com/wilsonbrito/brito && cd brito
282
+ npm install
283
+ npm run dev # roda via tsx
284
+ npm run typecheck
285
+ npm test # 190+ testes, incluindo um servidor MCP real e um REPL real
286
+ ```
287
+
288
+ | Caminho | O quê |
289
+ |---|---|
290
+ | `src/graph/` | indexador (tree-sitter), suporte a `.svelte/.vue/.astro`, aliases de import, store Ladybug (Kùzu) |
291
+ | `src/skills/` | store, lint, reflexão, journal, consolidação |
292
+ | `src/agent/` | loop do agente, prompts, subagentes, backend da CLI `claude` |
293
+ | `src/tools/` | tools de grafo, memória, skills, arquivos e shell |
294
+ | `src/mcp/` | servidor MCP |
295
+ | `src/repl.ts`, `src/ui/` | interface de terminal |
296
+ | `src/desktop/` | `brito gui-serve`: o backend com que a janela do desktop conversa (JSON por stdio) |
297
+ | `desktop/` | janela Electron e empacotamento (`package.mjs`); `npm run bundle` gera o backend em arquivo único que ela usa |
298
+
299
+ ## Licença
300
+
301
+ [PolyForm Noncommercial 1.0.0](LICENSE): uso, estudo e modificação livres para qualquer fim não comercial (uso pessoal, pesquisa, educação, hobby, ONGs). Uso comercial não é permitido. É código disponível (source-available), não open source pela definição da OSI. Precisa de licença comercial? Abra uma issue.