MÓDULO 2.2

⚙️ Variáveis e configuração

Dois .env, um config.ts, um TOML do core e um bearer token. Quem lê o quê e por quê.

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

🗂️ Arquitetura de configuração

OpenHuman tem três camadas de configuração, cada uma com escopo, formato e consumidor distintos. Misturá-las é o erro #1 de onboarding.

🎯 As três camadas

  • 1.
    .env raiz — Rust core + Tauri shell + scripts. Carregado por scripts/load-dotenv.sh.
  • 2.
    app/.env.local — frontend Vite. Só vars VITE_* chegam ao browser.
  • 3.
    TOML do coreConfig struct em src/openhuman/config/schema/types.rs, com overrides por env via load.rs.

✓ Modelo mental correto

  • Browser: só vê VITE_* de app/.env.local
  • Rust: lê .env raiz + TOML
  • Tauri shell: ponte entre os dois, lê .env raiz

✗ Armadilhas comuns

  • Setar VITE_FOO no .env raiz esperando que o browser leia
  • Setar OPENHUMAN_* em app/.env.local esperando que o Rust leia
  • Acessar import.meta.env fora de config.ts

💡 Dica prática

Quando configurar uma feature nova, pergunte: quem consome essa variável? Se for browser → app/.env.local com prefixo VITE_. Se for Rust → .env raiz ou TOML. Se for shell Tauri (Rust mas perto da janela) → .env raiz.

2

📄 .env raiz e load-dotenv.sh

O .env raiz cobre tudo que não é browser: Rust core, Tauri shell, scripts de teste, ferramentas auxiliares. Comece copiando o template.

⌨️ Setup inicial

# Da raiz do repo
cp .env.example .env

# Carregar para sua sessão shell
source scripts/load-dotenv.sh

# Conferir variáveis exportadas
env | grep OPENHUMAN_

📋 Categorias do .env raiz

  • App environmentOPENHUMAN_APP_ENV=production|staging
  • Backend APIBACKEND_URL (default https://api.tinyhumans.ai)
  • AuthJWT_TOKEN para skills OAuth proxy e scripts de debug
  • Core process — host, port, RPC URL, token, run mode, binary path
  • Config overrides — modelo default, AI binary, paths de storage
  • Logging & proxy — verbosidade, proxy HTTP/HTTPS

📌 Exemplo de bloco real

# [optional] Default: 7788
OPENHUMAN_CORE_PORT=7788
# [optional] Default: http://127.0.0.1:7788/rpc
OPENHUMAN_CORE_RPC_URL=http://127.0.0.1:7788/rpc
# [optional] Run mode: child (default) | inprocess
OPENHUMAN_CORE_RUN_MODE=child
# Core RPC bearer token. Single source of truth para /rpc auth.
# OPENHUMAN_CORE_TOKEN=

Tags [required] vs [optional]

Cada linha indica se é obrigatória. [optional] com comentário mostra o default.

Quando exportar manualmente

Para rodar openhuman-core serve direto, cargo tests fora dos scripts, ou debug de scripts src/bin/.

load-dotenv.sh é idempotente

Pode rodar várias vezes na mesma sessão. pnpm dev:app já roda automático.

Não commitar

.env está no .gitignore. Só .env.example vai pro repo.

3

🌐 app/.env.local e a convenção VITE_*

Vite expõe ao browser apenas vars com prefixo VITE_. É proteção de segurança — sem o prefixo, valores ficam no servidor de dev e nunca aparecem no bundle.

⌨️ Setup do frontend

# Da raiz
cp app/.env.example app/.env.local

# Editar valores conforme necessário
# Em dev você raramente precisa mudar nada

📐 Precedência do RPC URL

Runtime, do mais alto para o mais baixo:

  1. Campo de RPC URL na tela de login (salvo via app/src/utils/configPersistence.ts)
  2. Comando Tauri core_rpc_url (porta que o sidecar bundled escuta)
  3. Valor de VITE_OPENHUMAN_CORE_RPC_URL
  4. Hardcoded http://127.0.0.1:7788/rpc

📌 Variáveis principais

VITE_OPENHUMAN_CORE_RPC_URL=http://127.0.0.1:7788/rpc
VITE_TELEGRAM_BOT_USERNAME=openhuman_bot
VITE_SKILLS_GITHUB_REPO=tinyhumansai/openhuman-skills
# VITE_BACKEND_URL=https://staging-api.tinyhumans.ai
# VITE_OPENHUMAN_APP_ENV=staging
# VITE_GA_MEASUREMENT_ID=
# VITE_SENTRY_DSN=
1

Desktop user nunca edita

Configurações de RPC URL e backend.

Usuário final preenche tudo na tela de login. O .env.local é para dev e CI.

2

Web preview / Storybook

Sem Tauri = sem core.

Nesse contexto VITE_BACKEND_URL importa, porque não há handshake do core para resolver api_url.

3

Sentry source-map upload

CI-only.

SENTRY_AUTH_TOKEN, SENTRY_URL, SENTRY_ORG, SENTRY_PROJECT — em branco local, populated em CI.

4

📑 config.ts: a single source of truth

app/src/utils/config.ts centraliza toda leitura de import.meta.env. Outros módulos importam de lá. Nunca consultam import.meta.env diretamente.

🎯 Regra dura

Citação direta do CLAUDE.md:

"Frontend config is centralized in app/src/utils/config.ts. Read VITE_* there and re-export — never import.meta.env directly elsewhere."

✓ FAZER

// algum-modulo.ts
import { CORE_RPC_URL } from '@/utils/config';

fetch(`${CORE_RPC_URL}/rpc`, ...);

✗ NÃO fazer

// algum-modulo.ts
const url = import.meta.env
  .VITE_OPENHUMAN_CORE_RPC_URL;

fetch(`${url}/rpc`, ...);

💡 Por que isso importa

Quando o time precisar trocar precedência (ex: introduzir um terceiro source), basta editar config.ts. Sem essa regra, refatoração vira caça ao tesouro pelo repo inteiro.

Tipagem

Exports tipados (string, boolean, etc.) — consumidores não fazem cast.

Defaults aqui

Fallback hardcoded fica em config.ts, não espalhado por componentes.

Testes

Vitest mocka config.ts, não import.meta.env. Isolamento melhor.

Persistência

Override de runtime (tela de login) gravado em configPersistence.ts.

5

🔑 Variáveis críticas do core

Três variáveis controlam a comunicação Tauri↔core e podem te quebrar de formas confusas. Vale dedicar tempo agora.

1

OPENHUMAN_CORE_TOKEN

Bearer token por launch.

Desktop Tauri: seta automático — deixe em branco. Docker/cloud: obrigatório. Standalone: core grava em {workspace}/core.token (0o600).

# Gerar para Docker/cloud
openssl rand -hex 32
2

OPENHUMAN_WORKSPACE

Redireciona config + storage do core.

Default: ~/.openhuman. Em testes E2E, app/scripts/e2e-run-spec.sh cria diretório temp e limpa depois — isolamento entre specs.

3

OPENHUMAN_CORE_REUSE_EXISTING=1

Anexa a core externo.

Em vez de o Tauri spawnar seu próprio core, ele conecta em um já rodando (debug harness, instância manual). Útil para inspeção sem reiniciar tudo.

⚠️ Token mismatch

Se você bota um OPENHUMAN_CORE_TOKEN manual no .env mas o Tauri shell já gera o seu, dá conflito. Para desktop, deixe em branco e use scripts/print-core-token.sh para inspecionar o ativo.

6

🧪 Modo staging

OPENHUMAN_APP_ENV=staging é o switch que aponta o app inteiro para o backend de staging e um workspace isolado em ~/.openhuman-staging.

⌨️ Ativando staging

# .env raiz
OPENHUMAN_APP_ENV=staging
# BACKEND_URL=https://staging-api.tinyhumans.ai  # default já cobre

# app/.env.local
VITE_OPENHUMAN_APP_ENV=staging
VITE_BACKEND_URL=https://staging-api.tinyhumans.ai

🔬 O que muda

  • Workspace: ~/.openhuman-staging (separado de produção)
  • Token standalone: ~/.openhuman-staging/core.token
  • Backend: aponta para staging-api.tinyhumans.ai
  • Cobertura: testes manuais de features de backend sem tocar prod

💡 Quando usar

Sempre que tocar em endpoints novos do backend, autenticação, ou fluxos que afetam dados reais. Staging permite quebrar à vontade. Voltar a produção é só comentar o OPENHUMAN_APP_ENV.

Workspaces separados

Pode rodar prod e staging em paralelo — caches, tokens e configs não colidem.

Mirror Vite obrigatório

Só setar no .env raiz não basta — o frontend precisa do VITE_* equivalente.

Dados de teste

Staging tem usuários e dados sintéticos. Não confunda com produção.

Reset rápido

rm -rf ~/.openhuman-staging volta ao estado de primeira execução.

📚 Resumo do módulo

Três camadas: .env raiz, app/.env.local, TOML do core
Browser vê só VITE_*: prefixo é proteção, não estilo
config.ts é única fonte: nunca import.meta.env solto
TOKEN, WORKSPACE, REUSE: 3 vars críticas Tauri↔core
Staging é workspace isolado: ~/.openhuman-staging separado de prod
Mirror Vite: para staging, setar tanto raiz quanto VITE_*

Próximo módulo:

2.3 - Primeira execução: pnpm dev:app, debug runners e mock API