MÓDULO 2.1

🛠️ Setup do ambiente

Pré-requisitos, fork, dependências e o detalhe que derruba 9 em cada 10 instalações: a CLI vendorizada do Tauri.

6
Tópicos
45
Minutos
Básico
Nível
Prática
Tipo
1

📋 Pré-requisitos

OpenHuman é um monorepo híbrido: TypeScript no workspace app/ e crate Rust openhuman-core na raiz. Antes de qualquer pnpm install, você precisa de três toolchains funcionando em paralelo.

🎯 Stack mínima

  • Node 20+ (LTS recomendado) — runtime do Vite, ESLint, Vitest
  • pnpm via corepack enable — versão fixada pelo campo packageManager do package.json raiz
  • Rust stable via rustup — compila openhuman-core e o Tauri shell
  • Git — fork-based workflow exige remotes origin e upstream distintos

🍎 macOS

Xcode Command Line Tools (xcode-select --install). Brew opcional para utilities.

🐧 Linux

Pacotes de WebKit/GTK + build-essential. CEF runtime exige libs gráficas adicionais.

🪟 Windows

Visual Studio Build Tools + WebView2 runtime (já vem no Windows 11).

💡 Dica prática

Habilite Corepack antes de clonar: corepack enable. Assim o pnpm é instalado automaticamente na versão correta na primeira vez que você roda qualquer comando no repo. Sem isso, você pode acabar com uma versão divergente que quebra o lockfile.

Versão do Node

Use nvm ou fnm para fixar 20.x. Mais novo costuma funcionar mas não é garantido.

Toolchain Rust

Estável (não nightly). rustup component add rustfmt clippy para format e lint.

Espaço em disco

Reserve ~10 GB. target/ Rust e node_modules/ crescem rápido.

RAM

8 GB compila mas sofre. 16 GB+ é confortável para rodar dev:app + cargo check em paralelo.

2

🍴 Fork e clone do repositório

O fluxo é fork-based: origin aponta para o SEU fork (pra onde você empurra branches), e upstream aponta para tinyhumansai/openhuman (fetch-only). Esse layout é regra dura no CONTRIBUTING.md.

⌨️ Comandos exatos

# 1. Forkar tinyhumansai/openhuman no GitHub (UI)
# 2. Clonar o SEU fork:
git clone git@github.com:<your-username>/openhuman.git
cd openhuman

# 3. Adicionar upstream
git remote add upstream git@github.com:tinyhumansai/openhuman.git
git fetch upstream

# 4. Verificar
git remote -v
# origin    git@github.com:<your-username>/openhuman.git  (fetch/push)
# upstream  git@github.com:tinyhumansai/openhuman.git     (fetch/push)

🔄 Já clonou upstream direto? Conserte uma vez:

git remote rename origin upstream
git remote add origin git@github.com:<your-username>/openhuman.git
git fetch upstream

✓ O que FAZER

  • Branchar de upstream/main: git checkout -b feat/x upstream/main
  • Push para origin (seu fork)
  • PR contra tinyhumansai/openhuman:main
  • Manter main local limpo, atualizado por fast-forward

✗ O que NÃO fazer

  • Push direto em upstream (polui branches do repo oficial)
  • Commitar em main (CLAUDE.md proíbe explicitamente)
  • Trocar a URL de origin para upstream
  • Usar git push --force em main

SSH vs HTTPS

SSH evita prompts de credencial. Gere chave com ssh-keygen -t ed25519 e adicione no GitHub.

Sync com upstream

git fetch upstream && git rebase upstream/main antes de abrir PR para evitar conflitos.

3

📦 pnpm install: instalando dependências

Da raiz, pnpm install resolve o workspace inteiro de uma vez — TypeScript, ESLint, Vite, Vitest, Tauri JS APIs e tudo no workspace app/. Use pnpm: npm e yarn quebram a resolução.

⌨️ Comando

# Da raiz do repo
pnpm install

# Verificar workspace foi reconhecido
pnpm -r ls --depth -1

📊 Anatomia do workspace

  • openhuman-repo — pacote raiz privado, define scripts agregados e packageManager
  • openhuman-app — workspace app/, React + Vite + Tauri (v0.53.45)
  • packages/tauri-plugin-ptt — Push-to-Talk plugin (Swift + Rust, iOS-only)
1

Resolução de lockfile

pnpm lê pnpm-lock.yaml e pnpm-workspace.yaml.

Workspace packages são symlinkados — alterações em um pacote são vistas pelos outros sem reinstall.

2

Husky hooks

Setup automático pós-install.

Pre-push roda pnpm rust:check — falha se o Tauri shell não compila.

3

tauri:ensure invocado

Postinstall garante CLI correta.

Roda scripts/ensure-tauri-cli.sh — instala a CLI vendorizada se não estiver presente.

Comandos da raiz

Sempre rode da raiz — pnpm dev delega para app automaticamente.

Limpando estado

Em problemas: pnpm store prune + rm -rf node_modules && pnpm install.

Cache do pnpm

Reuso global do .pnpm-store torna reinstalls quase instantâneos.

Workspaces aninhados

pnpm --filter openhuman-app <cmd> direciona comando para subworkspace.

4

🧱 A CLI vendorizada do Tauri (e por que ela existe)

O runtime do OpenHuman é CEF (Chromium Embedded Framework), não o WebView nativo padrão do Tauri. Só a CLI vendorizada em app/src-tauri/vendor/tauri-cef/crates/tauri-cli sabe empacotar Chromium em Contents/Frameworks/ do bundle final.

⚠️ Atenção: stock CLI quebra

Usar @tauri-apps/cli oficial produz um bundle quebrado que crasha no boot com:

panic: cef::library_loader::LibraryLoader::new

O panic acontece porque o loader procura Chromium em Contents/Frameworks/ e não encontra — a CLI stock não copia para lá.

⌨️ Como a vendored CLI entra automaticamente

# pnpm dev:app e qualquer cargo tauri script chamam:
pnpm tauri:ensure

# Que executa:
scripts/ensure-tauri-cli.sh

# Se sobrescrita, reinstalar manualmente:
cargo install --locked \
  --path app/src-tauri/vendor/tauri-cef/crates/tauri-cli

💡 Dica prática

Se algum colega instalou cargo install tauri-cli ou usou cargo install --force em outro projeto, ele pode ter sobrescrito a vendored. O sintoma é pnpm dev:app abrir uma janela em branco que crasha em alguns segundos. Solução: rodar o comando de install --path acima.

✓ Sinais de CLI correta

  • Janela abre e renderiza UI
  • cargo tauri --version reporta versão CEF-aware
  • Bundle .app tem Frameworks/ populado

✗ Sinais de CLI errada

  • Panic em LibraryLoader::new
  • Bundle sem Contents/Frameworks/
  • Janela abre em branco e fecha

iOS é diferente

pnpm tauri:ios:dev usa @tauri-apps/cli@^2 stock via npx — iOS não usa CEF.

Localização vendor

app/src-tauri/vendor/tauri-cef/ é um fork interno do Tauri com patches CEF.

Por que CEF?

Embedded providers (WhatsApp, Slack, etc.) precisam de Chromium consistente cross-platform.

Lock file

--locked é importante — sem ele cargo install pode pegar versões diferentes de deps.

5

🦀 cargo check do core

Antes de subir a UI, valide que o crate Rust compila. São dois Cargo.toml: o da raiz (core) e o do shell Tauri em app/src-tauri/. Cada um precisa do seu check.

⌨️ Comandos

# Core lib + binário openhuman-core
cargo check --manifest-path Cargo.toml
cargo build --manifest-path Cargo.toml --bin openhuman-core

# Tauri shell
cargo check --manifest-path app/src-tauri/Cargo.toml
# Atalho equivalente:
pnpm rust:check

📦 Binários auxiliares

O Cargo.toml raiz também define helpers em src/bin/:

  • slack-backfill — script para popular histórico Slack
  • gmail-backfill-3d — backfill de 3 dias de email

⏱️ Primeira compilação demora

A primeira cargo build pode levar 5-15 minutos porque baixa e compila ~400 crates. Builds incrementais subsequentes são na casa de segundos. Não cancele achando que travou.

check vs build

check só verifica tipos (rápido). build gera o binário linkado.

target/ compartilhado

Core e shell compartilham deps. Limpar target/ recompila tudo.

Release vs debug

Dev usa debug. --release é ~10× mais lento para compilar mas roda muito mais rápido.

Falhas comuns

Faltam libs de sistema (libssl, libwebkit) — instale pelo gerenciador da sua distro.

6

✅ Verificação final do setup

Quatro comandos confirmam que tudo está pronto. São os mesmos checks do CI — passar localmente significa que seu PR não vai vermelhar por gosto.

⌨️ Check final

# Da raiz
pnpm typecheck     # tsc --noEmit (alias: pnpm compile)
pnpm lint          # ESLint --cache
pnpm format:check  # Prettier check + cargo fmt --check
pnpm rust:check    # cargo check do Tauri shell

✓ Tudo verde significa

  • TS compila sem erro de tipo
  • ESLint não tem violações
  • Código formatado (Prettier + rustfmt)
  • Tauri shell Rust compila

✗ Não force push se

  • Algum check acima falha
  • Você não rodou format antes
  • Husky pre-push reporta erro

💡 Auto-format antes de commit

Rode pnpm format (sem o :check) periodicamente — ele escreve as correções. Não precisa pensar em estilo de código no review.

typecheck = compile

São aliases no package.json do workspace app. Mesmo comando, dois nomes históricos.

ESLint --cache

Cache em .eslintcache torna runs subsequentes quase instantâneos.

--no-verify

Só use quando o hook falha em código que você NÃO tocou (breakage pré-existente).

Coverage gate

CI exige ≥80% de cobertura nas linhas alteradas — testes desde já.

📚 Resumo do módulo

Stack mínima: Node 20+, pnpm via Corepack, Rust estável, Git com SSH
Fork-based workflow: origin = seu fork, upstream = tinyhumansai/openhuman fetch-only
pnpm da raiz: resolve workspace inteiro; npm/yarn quebram resolução
CLI vendorizada CEF: stock cli quebra com panic CEF; pnpm tauri:ensure mantém certa
Dois Cargo.toml: core (raiz) e shell (app/src-tauri/)
Quatro checks finais: typecheck, lint, format:check, rust:check

Próximo módulo:

2.2 - Variáveis e configuração: .env raiz, app/.env.local e o TOML do core