Início/Trilha 3 · Técnicas Avançadas/Módulo 3.6
MÓDULO 3.6

⚙️ Daemon, Sidecar IPC & Multi-namespace

A engenharia do daemon. Multi-namespace em paralelo, sidecar IPC, debug via inspect tools.

9
Tópicos
~70 min
Duração
Avançado
Nível
Eng
Foco

🏁 Resultado: Você opera múltiplos namespaces em paralelo (Playwright + dev + projetos reais), debuga via inspect tools e entende a arquitetura interna do daemon.

1

🎛️ pnpm tools-dev — único entrypoint de lifecycle

start/stop/run/status/logs/inspect/check.

O que é

Um único comando padrão para gerenciar tudo:

pnpm tools-dev start --namespace default
pnpm tools-dev stop --namespace experiments
pnpm tools-dev status              # lista todos
pnpm tools-dev logs --namespace default --json
pnpm tools-dev inspect desktop screenshot
pnpm tools-dev check                # health check global

Subcomandos cobrem todo o lifecycle. Não há "outros scripts shell mágicos" — uma porta de entrada.

Por que aprender

Sem entrypoint único, time inventa scripts paralelos, README desatualiza, dev novo perde dia 1 entendendo "qual comando usar". Com um ponto, onboarding é trivial. Convergência operacional.

Conceitos-chave

  • tools/dev/: source code do CLI
  • Subcomandos: start, stop, restart, status, logs, inspect, check
  • --namespace flag: isolamento por namespace
  • --json output: machine-readable para scripts
2

📛 Stamps tipados de 5 campos

app · mode · namespace · ipc · source.

O que é

Cada processo do OD tem um "stamp" tipado:

{
  app: "daemon" | "web" | "desktop" | "playwright",
  mode: "dev" | "prod" | "test",
  namespace: "default" | "experiments" | "playwright",
  ipc: "/tmp/open-design/ipc/<ns>/<app>.sock",
  source: "tools-dev" | "manual" | "ci"
}

Stamp é serializado em logs, environment vars, e display. Você sempre sabe qual processo emitiu uma mensagem.

Por que aprender

Multi-namespace = múltiplos processos paralelos. Sem stamp, logs viram "qual daemon escreveu isso?". Com stamp, debug é trivial: grep "namespace=experiments".

Conceitos-chave

  • 5 fields: app, mode, namespace, ipc, source
  • Tipado: TypeScript valida no boot
  • JSON line in logs: grep-friendly
  • UI badge: stamp aparece na top-bar do web
3

🔌 Sidecar IPC em /tmp/open-design/ipc/<ns>/<app>.sock

STATUS, EVAL, SCREENSHOT, CONSOLE, CLICK, SHUTDOWN.

O que é

Cada processo expõe um Unix socket em /tmp/open-design/ipc/<namespace>/<app>.sock. Outro processo (ou tools-dev) pode mandar comandos:

  • STATUS — devolve estado atual
  • EVAL — executa JS no contexto do app web
  • SCREENSHOT — devolve PNG
  • CONSOLE — captura logs do console.log
  • CLICK — automação básica
  • SHUTDOWN — graceful termination

Por que aprender

Sidecar IPC é a ponte que torna o desktop "inspetável" sem dev tools manuais. tools-dev pode pedir screenshot, capturar console, automatizar click — sem testing harness próprio.

Conceitos-chave

  • Unix domain socket: /tmp path por namespace
  • Comando JSON: {type: "STATUS"} → resposta JSON
  • packages/sidecar-proto: tipos compartilhados
  • packages/sidecar: implementação cliente/server
  • Reload-safe: socket recriado em cada start
4

🌳 OD_DATA_DIR e --namespace

Isolamento de árvore .od/.

O que é

Variável OD_DATA_DIR aponta pra raiz do estado. Combinada com --namespace foo, vira $OD_DATA_DIR/.od-foo/:

$OD_DATA_DIR/
├── .od/                    # namespace 'default'
│   └── app.sqlite
├── .od-experiments/        # namespace 'experiments'
│   └── app.sqlite
└── .od-playwright/         # namespace 'playwright' (CI/test)
    └── app.sqlite

Por que aprender

Sem isolamento, Playwright sobrescreve seus dados reais. Com isolamento, CI roda em paralelo sem conflito. Multi-namespace = multi-projeto sem fricção.

Conceitos-chave

  • OD_DATA_DIR: root path (default: cwd)
  • --namespace flag: sufixo da árvore
  • .od-<ns>/ pattern: visível no fs
  • SQLite separado por ns: sem race condition
5

🧬 Por que namespaces

Playwright, beta, projetos reais sem colisão.

O que é

3 namespaces canônicos:

default

Seu trabalho real

playwright

Tests E2E sem colisão

experiments

Tente algo arriscado sem afetar real

Por que aprender

Cada uma tem propósito. Playwright em namespace separado = test não polui SQLite. Experiments separado = você pode ir agressivo sem perder trabalho. Convenção de namespaces salva pesadelos.

Conceitos-chave

  • Naming convention: snake_case ou kebab-case
  • Sem limite: crie quantos quiser
  • Cleanup manual: rm -rf .od-foo/
  • Cross-ns reference: impossível por design
6

📸 tools-dev inspect desktop screenshot

E2E sem harness próprio.

O que é

tools-dev tem subcomandos inspect que falam com sidecar IPC para automação:

pnpm tools-dev inspect desktop screenshot --output ss.png
pnpm tools-dev inspect web eval "document.title"
pnpm tools-dev inspect web console --since 5m
pnpm tools-dev inspect daemon health

Sem Playwright, sem Cypress, sem dev tools manuais — tudo via CLI.

Por que aprender

É como o sidecar IPC vira útil de fato. Inspect = "eu quero saber o que está rolando, sem abrir DevTools manualmente". Útil em debug, CI, demo automatizada.

Conceitos-chave

  • screenshot: PNG do desktop atual
  • eval <js>: executa JS no contexto, retorna resultado
  • console: captura logs recentes
  • health: daemon vivo? quantos clients conectados?
  • scriptable: use em bash, node scripts, CI
7

🖥️ apps/desktop Electron shell

Discovery de URL via IPC, sem adivinhar porta.

O que é

App desktop é Electron fininho: não roda Web internamente, mas descobre a URL do Web via sidecar IPC. Quando o daemon sobe, ele anuncia web_url: http://localhost:3000 via socket. Desktop conecta, abre webview na URL.

Por que aprender

Discovery via IPC > hardcoded port: Web pode estar em 3000 ou 3001 ou random. Desktop não precisa adivinhar. Robustez por design.

Conceitos-chave

  • apps/desktop/src/main/: processo principal Electron
  • IPC discovery: daemon publica web_url
  • Webview wrapper: não <BrowserWindow> com http remoto
  • Native menu: File, Edit, Window — convenção macOS
8

📦 sidecar-proto vs sidecar vs platform

Separação genérico/específico.

O que é

Três pacotes em packages/:

  • sidecar-proto: tipos TS compartilhados (Stamp, Command, Response) — zero dependências
  • sidecar: implementação cliente/server reutilizável (qualquer projeto pode usar)
  • platform: abstração OS (paths /tmp em mac/linux vs %TEMP% em windows)

Por que aprender

Separação genérico/específico = packages reutilizáveis. sidecar-proto e sidecar não são OD-específicos; podem virar lib pública. Saber a separação = saber onde contribuir, onde fazer fork.

Conceitos-chave

  • sidecar-proto: contracts puros (TS types)
  • sidecar: implementation reusable
  • platform: OS-specific glue
  • No circular deps: proto → sidecar → platform → daemon
9

📜 Logs estruturados em .tmp/tools-dev/<ns>/logs/

Debug: pnpm tools-dev logs --namespace <name> --json.

O que é

Logs em formato NDJSON (newline-delimited JSON):

{"ts":"2026-05-02T15:30:01Z","level":"info","app":"daemon","ns":"default","msg":"agent spawn","cli":"claude"}
{"ts":"2026-05-02T15:30:02Z","level":"warn","app":"web","ns":"default","msg":"slow render","duration_ms":820}
...

grep, jq e tools-dev logs entendem o formato.

Por que aprender

NDJSON > texto livre quando há muitos eventos. Filtragem mecânica é trivial: jq 'select(.level == "warn")'. Multi-namespace = filtragem por ns.

Conceitos-chave

  • NDJSON: 1 evento por linha
  • Padrão de campos: ts, level, app, ns, msg + dados
  • Rotation: arquivo > 50 MB rotaciona
  • tools-dev logs --grep: filtragem rápida

🛠️ Hands-on

Brief: Rodar 2 namespaces em paralelo (default + experiments), com SQLite isolada cada um. Tirar screenshot do desktop em cada um.

  1. Inicia default: pnpm tools-dev start --namespace default
  2. Inicia experiments em paralelo: pnpm tools-dev start --namespace experiments
  3. Verifique status: pnpm tools-dev status mostra ambos rodando
  4. Veja árvores .od separadas: ls -la .od/ .od-experiments/
  5. Inspect desktop default: pnpm tools-dev inspect desktop screenshot --namespace default --output default.png
  6. Inspect desktop experiments: idem com --namespace experiments
  7. Verifique: ambos PNGs salvos; cada um tem badge no top mostrando seu namespace.
  8. Cleanup experiments: pnpm tools-dev stop --namespace experiments && rm -rf .od-experiments/

Comando

pnpm tools-dev status --json | jq
pnpm tools-dev logs --namespace experiments --json | jq 'select(.level == "warn")'

📚 Fontes

No repositório

  • tools/dev/
  • apps/desktop/src/main/
  • packages/sidecar-proto/
  • packages/sidecar/
  • apps/AGENTS.md
  • tools/AGENTS.md

Externas

  • Unix domain sockets — Linux/macOS docs
  • Electron BrowserWindow / webview docs
  • NDJSON spec (ndjson.org)

📌 Resumo do Módulo

1. pnpm tools-dev é o entrypoint único: start, stop, status, logs, inspect, check.

2. Stamps tipados (app, mode, namespace, ipc, source) tornam debug grep-able.

3. Sidecar IPC em /tmp/open-design/ipc/<ns>/<app>.sock — STATUS, EVAL, SCREENSHOT, etc.

4. OD_DATA_DIR + --namespace = árvores .od-<ns>/ isoladas.

5. Namespaces canônicos: default (real), playwright (CI), experiments (arriscar).

6. tools-dev inspect = E2E sem harness; screenshot, eval, console direct.

7. apps/desktop é Electron fino; descobre web URL via IPC.

8. Separação sidecar-proto / sidecar / platform = packages reutilizáveis.

9. NDJSON logs em .tmp/tools-dev/<ns>/logs/ — filtrável por jq/grep.

Você completou o curso! Volte ao início:

🎨 Voltar à Landing →
← Módulo 3.5 Início do Curso 🎨