Contribuindo com o GarraIA
Obrigado pelo interesse em contribuir! Este documento descreve como configurar o ambiente, as convenções do projeto e o processo de envio de contribuições.
Código de Conduta
Ao participar deste projeto, você concorda em ser respeitoso, inclusivo e construtivo nas interações com outros membros da comunidade.
Pré-requisitos
| Ferramenta | Versão mínima | Instalação |
|---|---|---|
| Rust | 1.97 | rustup update stable |
| Git | qualquer | git-scm.com |
| FFmpeg | 6.x | apt install ffmpeg / brew install ffmpeg |
| Node.js (opcional) | 20+ | Para rodar servidores MCP de teste |
Para features de voz (garraia-voice): CUDA Toolkit 12+ (NVIDIA) ou Metal (Apple Silicon).
Configurar o ambiente de desenvolvimento
1. Fazer fork e clonar
git clone https://github.com/SEU_USUARIO/GarraRUST.git
cd GarraRUST
git remote add upstream https://github.com/michelbr84/GarraRUST.git
2. Fixar a toolchain Rust localmente (recomendado)
O workspace exige Rust 1.97+ (ver a tabela de pré-requisitos e o job "MSRV
check (1.97)" do CI). Sem isso declarado em algum lugar, rustup usa
qualquer stable que já estiver instalada — mesmo abaixo do piso — e o erro
só aparece depois, no meio de um cargo check.
bash scripts/setup-toolchain.sh
O script instala a 1.97 (se faltar) e roda rustup override set 1.97 só
para este diretório. Note que isso não é um rust-toolchain.toml
commitado no repo — essa abordagem foi tentada (issue #1452, PR #1454) e
quebrou os jobs de CI que fazem cross-compile com targets extras (Android,
Windows ARM64), porque o arquivo tem precedência sobre a toolchain que
dtolnay/rust-toolchain acabou de instalar com esses targets. O override do
rustup fica em ~/.rustup/settings.toml, no seu HOME — nunca alcança o
CI.
3. Compilar o workspace
cargo build --workspace
4. Executar os testes
# Suite completa
cargo test --workspace
# Crate específica
cargo test -p garraia-gateway
# Com saída de log
cargo test --workspace -- --nocapture
5. Rodar o servidor localmente
cargo run --package garraia-cli -- init
cargo run --package garraia-cli -- start
6. Verificar saúde do servidor
curl http://127.0.0.1:3888/health
# {"status":"ok","version":"0.9.0-dev"}
7. Construir a documentação
# Instalar mdBook
cargo install mdbook
# Construir e servir localmente
mdbook serve docs
# Acesse http://localhost:3000
Estrutura do projeto
crates/
├── garraia-cli/ # Ponto de entrada da CLI (main.rs)
├── garraia-gateway/ # Servidor HTTP/WebSocket (Axum 0.8)
├── garraia-config/ # Parsing e hot-reload de configuração
├── garraia-channels/ # Adaptadores de canais (Telegram, Discord, Slack...)
├── garraia-agents/ # Provedores LLM + AgentRuntime
├── garraia-voice/ # Pipeline de voz (STT + TTS)
├── garraia-db/ # SQLite + busca vetorial (rusqlite)
├── garraia-plugins/ # Sandbox de plugins WASM (Wasmtime)
├── garraia-media/ # Processamento de PDF e imagens
├── garraia-security/ # Vault de credenciais + autenticação
├── garraia-skills/ # Parser e instalador de skills Markdown
└── garraia-common/ # Tipos compartilhados + erros
apps/
└── garraia-mobile/ # Cliente Flutter Android (Riverpod + go_router)
Fluxo de trabalho
1. Sincronizar com upstream
git fetch upstream
git checkout main
git merge upstream/main
2. Criar um branch
git checkout -b feat/nome-da-feature # nova feature
git checkout -b fix/descricao-do-bug # correção de bug
git checkout -b docs/pagina-atualizar # documentação
3. Verificar antes de enviar
Execute todos os checks antes de abrir o PR:
cargo fmt --all # formatar
cargo clippy --workspace --exclude garraia-desktop --all-targets -- -D warnings # linting
cargo test --workspace --exclude garraia-desktop # testes
cargo deny check # dependências
O --exclude garraia-desktop não é opcional. O build.rs dele precisa
das bibliotecas de sistema GTK/glib e de um sidecar do Windows que uma
máquina limpa não tem, então um --workspace puro falha em algo que não é a
sua mudança. O CI exclui pelo mesmo motivo; o desktop é construído à parte
por scripts/build-installer.ps1.
O pacote da CLI chama-se garraia (binário garra), não garraia-cli —
cargo test -p garraia-cli falha com "did not match any packages".
4. Fazer commits
Use o formato Conventional Commits:
git commit -m "feat(channels): adiciona suporte ao canal WhatsApp Business"
git commit -m "fix(agents): corrige vazamento de memória no streaming SSE"
git commit -m "docs(api): documenta endpoint POST /api/sessions"
git commit -m "test(gateway): adiciona testes de integração para auth JWT"
git commit -m "refactor(db): simplifica SessionStore com query builder"
git commit -m "chore(deps): atualiza axum para 0.8.4"
Tipos aceitos: feat, fix, docs, test, refactor, chore, perf, ci
Limite de 72 caracteres no assunto. Use o imperativo: "adiciona" (não "adicionada").
5. Deixar um fragmento de changelog
Não edite o CHANGELOG.md direto. Cada PR deixa um arquivo em
changelog.d/<seção>/<numero>-<slug>.md:
cat > changelog.d/added/1234-minha-feature.md <<'EOF'
- **Titulo curto do que mudou (#1234).** O paragrafo explica o que a pessoa
que usa vai notar, e por que a mudanca e assim e nao de outro jeito.
EOF
python3 scripts/changelog/assemble.py --check # valida os fragmentos
Seções válidas: added, changed, deprecated, removed, fixed,
security (Keep a Changelog 1.1.0).
A razão é concreta: arquivos diferentes nunca conflitam, e era a colisão na
seção [Unreleased] que fazia todo par de PRs paralelos precisar de um
merge de resolução. Juntar os fragmentos no CHANGELOG.md é passo de
release (--write, ver docs/releasing.md), não de PR.
Detalhe em changelog.d/README.md.
6. Abrir o Pull Request
git push origin feat/nome-da-feature
Abra o PR no GitHub apontando para main. Preencha o template completamente.
Convenções de código
Rust
- Sem
unwrap()em código de produção — use?ouexpect()com mensagem descritiva apenas em testes - Sem concatenação de strings em SQL — use sempre a macro
params! - Sem secrets em logs — nunca registre
ANTHROPIC_API_KEY,GARRAIA_JWT_SECRETetc. AppStateéArc<AppState>— importe viacrate::state::AppState- Axum 0.8:
FromRequestPartsusa AFIT nativo — sem#[async_trait] - Docstrings com
///para funções públicas,//!para módulos - Erros via
thiserror; usegarraia_common::Errorpara erros cross-crate
Flutter
- State management: Riverpod com code generation (
@riverpod) - Navigation: go_router com redirect de autenticação
- HTTP: Dio com
_AuthInterceptorpara JWT bearer automático - Nunca use
withOpacity()— usewithValues(alpha:) - Docstrings
///para classes e métodos públicos
Documentação
- PT-BR para guias do usuário e documentação interna
- EN para comentários de código, README principal e PR descriptions
- Nenhum placeholder como
TODO,...ou<inserir aqui>
Prioridades atuais
| Prioridade | Issue | Descrição |
|---|---|---|
| P0 | #104 | Website: garraia.org com páginas de comparação |
| P0 | #105 | Comunidade Discord |
| P1 | #106 | Skills iniciais embutidas |
| P1 | #108 | Roteamento multi-agente |
| P1 | #80 | MCP: resources, prompts, HTTP transport |
| P1 | #74 | Hardening de segurança |
| P2 | #72 | Suite de testes e benchmarks |
| P2 | #73 | CI/CD: matrix builds, crates.io, Docker |
Adicionando um novo provedor LLM
- Crie
crates/garraia-agents/src/providers/meu_provedor.rs - Implemente o trait
LlmProvider - Registre em
providers/mod.rs - Adicione à configuração de exemplo em
docs/src/providers.md - Adicione testes de integração em
tests/providers/
Adicionando um novo canal
- Crie
crates/garraia-channels/src/meu_canal.rs - Implemente o trait
Channel - Registre no bootstrap em
crates/garraia-gateway/src/bootstrap.rs - Documente em
docs/src/channels.mde criedocs/src/guides/connect-meu-canal.md
Encontrando algo para trabalhar
- Good first issues
- Help wanted
- ROADMAP.md (visão por fase) e TODO.md (fila operacional)
Comente em uma issue antes de começar a trabalhar para evitar esforço duplicado.
Acompanhamento e milestones
Planejamento de releases e ciclos vive no ROADMAP.md (visão por fase) e no TODO.md (fila operacional), com um tracker interno para sequenciamento — o Linear foi descontinuado em 2026-08-18 e os IDs GAR-xxx que aparecem em planos e ADRs são históricos. Por design, milestones do GitHub não são utilizados neste repositório.
GitHub Issues neste repositório serve a três propósitos restritos:
- Bugs reportados externamente pela comunidade.
- Issues de automação geradas por workflows (ex.:
garra-routine-trigger.yml, rotuladas comautomation+garra-routine). - Discussões pontuais que precisem de threading público.
Trabalho interno ativo (slices, planos, refactors, dependências) é rastreado em plans/ (um plano por slice; índice em plans/README.md) e correlacionado com PRs por título / branch. Se você for um colaborador externo procurando saber o que está em andamento, prefira o ROADMAP.md e o TODO.md na raiz do repositório.
Comunicação
- Discord: discord.gg/aEXGq5cS
- GitHub Issues: bugs, feature requests e discussões técnicas
- GitHub Discussions: perguntas gerais e ideias
- Segurança:
security@garraia.org(veja SECURITY.md)
Licença
Ao contribuir com este projeto, você concorda que suas contribuições serão licenciadas sob a Licença MIT.