🎛️ 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
📛 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
🔌 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
🌳 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
🧬 Por que namespaces
Playwright, beta, projetos reais sem colisão.
O que é
3 namespaces canônicos:
Seu trabalho real
Tests E2E sem colisão
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
📸 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
🖥️ 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
📦 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
📜 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.
- Inicia default:
pnpm tools-dev start --namespace default - Inicia experiments em paralelo:
pnpm tools-dev start --namespace experiments - Verifique status:
pnpm tools-dev statusmostra ambos rodando - Veja árvores .od separadas:
ls -la .od/ .od-experiments/ - Inspect desktop default:
pnpm tools-dev inspect desktop screenshot --namespace default --output default.png - Inspect desktop experiments: idem com
--namespace experiments - Verifique: ambos PNGs salvos; cada um tem badge no top mostrando seu namespace.
- 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.mdtools/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 →