MÓDULO 2.3

🚀 Primeira execução

Boot da Tauri shell, debug runners bounded, mock API e os quality checks que evitam PR vermelho.

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

pnpm dev vs pnpm dev:app

Dois comandos, dois propósitos. Confundi-los faz você passar minutos achando que algo "não funciona" quando na verdade você não subiu o core Rust.

pnpm dev

o Vite dev server.

  • • Hot reload de UI puro
  • • Sem core Rust → RPC falha
  • • Útil para storybook-like de componentes
  • • Boot em ~1 segundo

pnpm dev:app

Ciclo Tauri completo.

  • • Runtime CEF + core in-process
  • • Carrega scripts/load-dotenv.sh
  • • Chama pnpm tauri:ensure primeiro
  • • Boot 10-30s na primeira vez

⌨️ Comandos

# UI pura (sem core)
pnpm dev

# Desktop completo (RECOMENDADO)
pnpm dev:app

# Build de produção da UI
pnpm build

💡 Regra prática

99% do tempo você quer pnpm dev:app. Só use pnpm dev quando estiver iterando em CSS/UI pura e não precisa de invocar RPC do core.

Hot reload

Funciona em ambos. dev:app também recompila Rust quando muda app/src-tauri/.

Logs do core

Aparecem no terminal que rodou dev:app. Frontend logs no devtools.

Cmd+Q

Mata core junto com a GUI. CoreProcessHandle gerencia o lifecycle.

Devtools

Cmd+Opt+I (macOS) abre devtools do CEF para inspecionar a UI.

2

🔄 Fluxo de boot da Tauri shell

Desde PR #1061 não existe mais sidecar binário. O core roda como tokio task dentro do mesmo processo do Tauri host. Entender o boot ajuda a debugar.

1

Tauri host inicia

app/src-tauri/src/lib.rs

Registra IPC handlers, prepara janela, configura logging file-based.

2

CoreProcessHandle spawna o core

app/src-tauri/src/core_process.rs

Inicia o JSON-RPC server como tokio task. Gera OPENHUMAN_CORE_TOKEN hex aleatório. Bind em 127.0.0.1:<port>/rpc.

3

Frontend carrega no CEF

Vite dev server ou bundle estático

React monta a provider chain: Sentry → Redux → PersistGate → CoreStateProvider → ChatRuntimeProvider → HashRouter.

4

Handshake RPC via core_rpc_relay

Tauri IPC bridge

Frontend chama invoke('core_rpc_relay', ...) que faz HTTP autenticado para o core. Nunca fetch() direto — evita preflight CORS.

5

CoreStateProvider snapshot

Auth e core state

Chama fetchCoreAppSnapshot() — auth tokens vivem no core, não no redux-persist.

⚠️ Sidecar não existe mais

pnpm core:stage é no-op hoje — só ecoa mensagem. scripts/stage-core-sidecar.mjs foi removido. Não fique procurando processo separado de core.

🧰 Core standalone para debug

# Rodar core sozinho (sem Tauri)
./target/debug/openhuman-core serve

# Token gerado em:
#   {workspace}/core.token
# Default workspace: ~/.openhuman
# Staging:           ~/.openhuman-staging
3

🐛 Debug runners bounded

Rodar Vitest/WDIO/cargo direto despeja centenas de linhas no terminal. Os wrappers em scripts/debug/ limitam o stdout a um tamanho amigável e teiam o log completo em target/debug-logs/.

⌨️ Vitest (unit)

# Suite completa
pnpm debug unit

# Um arquivo
pnpm debug unit src/components/Foo.test.tsx

# Filtro por nome de teste
pnpm debug unit -t "renders empty state"

# Combinado + raw output
pnpm debug unit Foo -t "renders empty" --verbose

⌨️ WDIO E2E (um spec por vez)

pnpm debug e2e test/e2e/specs/smoke.spec.ts
pnpm debug e2e test/e2e/specs/cron-jobs-flow.spec.ts cron-jobs --verbose

⌨️ cargo (Rust)

# Delegates a scripts/test-rust-with-mock.sh
pnpm debug rust
pnpm debug rust json_rpc_e2e

⌨️ Inspecionar logs salvos

pnpm debug logs              # lista 50 mais recentes
pnpm debug logs last         # imprime o mais recente (~400 linhas)
pnpm debug logs unit         # mais recente com prefixo "unit"
pnpm debug logs last --tail 100

💡 Por que isso existe

Foi pensado para agentes (LLMs) lendo terminal output — context window é limitado. Mas humanos também ganham: você vê o resumo, e se quiser o detalhe, abre o log.

4

🎭 Mock API: backend de mentirinha

Para rodar testes sem rede real e sem flakes de timing, o repo tem um mock backend em scripts/mock-api-server.mjs. É compartilhado por Vitest unit, E2E e Rust tests.

📁 Arquivos relevantes

  • scripts/mock-api-core.mjs — core do mock (rotas e estado)
  • scripts/mock-api-server.mjs — server HTTP que embrulha o core
  • app/test/e2e/mock-server.ts — wrapper para WDIO E2E
  • scripts/test-rust-with-mock.sh — sobe mock antes de cargo test

🔧 Endpoints admin

  • GET /__admin/health — alive check
  • POST /__admin/reset — limpa estado entre testes
  • POST /__admin/behavior — injeta comportamento (latência, erro, payload custom)
  • GET /__admin/requests — lista requests recebidas (asserção)

⌨️ Rodar manualmente

# Sobe o mock e deixa rodando
pnpm mock:api

# Testes Rust com mock automático
pnpm test:rust

# Spec Rust específico
bash scripts/test-rust-with-mock.sh --test json_rpc_e2e

✓ Vantagens

  • Determinístico — sem flake de rede
  • Reset entre specs garante isolamento
  • Behavior injection cobre edge cases
  • Sem credenciais necessárias

✗ Limitações

  • Não cobre mudanças do backend real
  • Precisa atualizar mock quando contratos mudam
  • Lógica de negócio fica fora — só shape de payload
5

🧹 Quality checks pré-commit

Os mesmos comandos que rodam no CI estão disponíveis localmente. Rodar antes de empurrar evita PR vermelho e economiza ciclos de review.

⌨️ Suite completa

# TypeScript (alias de compile)
pnpm typecheck

# ESLint
pnpm lint

# Format (Prettier + cargo fmt)
pnpm format          # escreve
pnpm format:check    # só verifica

# Testes
pnpm test            # Vitest
pnpm test:coverage   # com cobertura
pnpm test:rust       # cargo via test-rust-with-mock.sh
pnpm rust:check      # cargo check do shell

📐 Husky pre-push

O hook automático roda pnpm rust:check antes de qualquer push. Falha:

  • • Você quebrou o Tauri shell → conserte e empurre novo commit
  • • Algo pré-existente quebrado e não tocado por você → --no-verify e nota no PR body

⚠️ Coverage gate

CI exige ≥80% nas linhas alteradas via .github/workflows/coverage.yml. diff-cover mistura lcov do Vitest e do cargo-llvm-cov. Abaixo do limite, o PR não mergeia. Adicione testes para o que você mudou, não só happy path.

format antes de commit

Rode pnpm format sem :check para escrever as correções. Sem stress no review.

test:coverage local

Antes de empurrar, rode local e veja se passa o gate antes do CI te avisar.

--no-verify regra

Só para breakage pré-existente. Documente no PR. Nunca para escapar de erros seus.

ESLint cache

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

6

🔧 Troubleshooting do primeiro boot

90% dos problemas de onboarding caem em três categorias. Saber identificar economiza horas.

1

Janela abre em branco e crasha

Sintoma: panic em cef::library_loader::LibraryLoader::new

Causa: CLI errada do Tauri foi sobrescrita.

# Fix
cargo install --locked \
  --path app/src-tauri/vendor/tauri-cef/crates/tauri-cli
2

Porta 7788 ocupada

Sintoma: core falha ao bindar; erro EADDRINUSE

Causa: outro processo (talvez um core órfão) já escuta.

# Achar o processo
lsof -i :7788
# Mata
kill -9 <pid>
# Ou: trocar porta
export OPENHUMAN_CORE_PORT=7799
3

RPC retorna 401 / "Unauthorized"

Sintoma: UI carrega mas todas as chamadas falham

Causa: token bearer divergente entre core e frontend.

# Inspecionar token ativo
bash scripts/print-core-token.sh

# Se você setou OPENHUMAN_CORE_TOKEN manual,
# remova do .env — Tauri gera o seu.

🔍 Outros sintomas e onde olhar

  • "Sidecar binary not found": docs antiga — sidecar foi removido em #1061; ignore
  • Vite recompila infinitamente: verifique se algum arquivo do Tauri está sendo gravado por linter em loop
  • Cargo build não termina: primeira vez é 5-15 min — aguarde
  • Erro de TypeScript em produção mas não local: pnpm typecheck usa tsc --noEmit — confira

💡 Dica final

Quando travar, vá para gitbooks/developing/architecture.md e gitbooks/developing/cef.md. São as fontes narrativas mais completas. CLAUDE.md resume; gitbooks aprofundam.

📚 Resumo do módulo

dev vs dev:app: o segundo sobe o core; o primeiro é só Vite
Boot in-process: não existe mais sidecar; core é tokio task
RPC via core_rpc_relay: nunca fetch() direto — evita CORS
Debug runners bounded: pnpm debug unit/e2e/rust/logs
Mock API compartilhado: unit, E2E e Rust usam o mesmo
Coverage gate ≥80%: linhas alteradas, não só happy path
3 falhas comuns: CEF panic, porta, token mismatch

Próxima trilha:

Trilha 3 - Arquitetura: como o core Rust, o shell Tauri e o frontend React conversam de verdade