Pular para o conteúdo principal

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​

FerramentaVersão mínimaInstalação
Rust1.97rustup update stable
Gitqualquergit-scm.com
FFmpeg6.xapt 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 ? ou expect() 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_SECRET etc.
  • AppState é Arc<AppState> — importe via crate::state::AppState
  • Axum 0.8: FromRequestParts usa AFIT nativo — sem #[async_trait]
  • Docstrings com /// para funções públicas, //! para módulos
  • Erros via thiserror; use garraia_common::Error para erros cross-crate

Flutter​

  • State management: Riverpod com code generation (@riverpod)
  • Navigation: go_router com redirect de autenticação
  • HTTP: Dio com _AuthInterceptor para JWT bearer automático
  • Nunca use withOpacity() — use withValues(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​

PrioridadeIssueDescrição
P0#104Website: garraia.org com páginas de comparação
P0#105Comunidade Discord
P1#106Skills iniciais embutidas
P1#108Roteamento multi-agente
P1#80MCP: resources, prompts, HTTP transport
P1#74Hardening de segurança
P2#72Suite de testes e benchmarks
P2#73CI/CD: matrix builds, crates.io, Docker

Adicionando um novo provedor LLM​

  1. Crie crates/garraia-agents/src/providers/meu_provedor.rs
  2. Implemente o trait LlmProvider
  3. Registre em providers/mod.rs
  4. Adicione à configuração de exemplo em docs/src/providers.md
  5. Adicione testes de integração em tests/providers/

Adicionando um novo canal​

  1. Crie crates/garraia-channels/src/meu_canal.rs
  2. Implemente o trait Channel
  3. Registre no bootstrap em crates/garraia-gateway/src/bootstrap.rs
  4. Documente em docs/src/channels.md e crie docs/src/guides/connect-meu-canal.md

Encontrando algo para trabalhar​

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:

  1. Bugs reportados externamente pela comunidade.
  2. Issues de automação geradas por workflows (ex.: garra-routine-trigger.yml, rotuladas com automation + garra-routine).
  3. 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.