Facade Scout
🛰️ Facade Scout
Aponta a câmera na fachada de um estabelecimento → Claude Vision lê a placa →
SerpAPI (Google Maps) casa o negócio real → scoring de lead-gen → e um agente cria
um site de uma página pro negócio. Dashboard web mostra os scans + gerações em tempo real.
- Repo:
github.com/marcuscaum/facade-scout· Clone local:C:\Users\User\facade-scout - Stack: Turborepo + bun workspaces.
apps/api(Bun + Elysia + Drizzle/SQLite),apps/web(Vite + React 19 + Leaflet),apps/mobile(Expo SDK 54),apps/worker(Bun, novo). - Prod: API
https://scout-api.kodama.solutions· dashboardhttps://scout.kodama.solutions· sites gerados em/s/<id>. - Deploy: GitHub Action em push pra
main→ builda dashboard + container da API → VPS Hermes (nginx native, SSE). CI builda combun install --frozen-lockfile(lockfile tem que estar commitado/atualizado).
🎯 Pivot principal (sessão 2026-06-27): geração de site no plano do user, custo $0
Antes: a API chamava o Anthropic SDK (streaming) pra gerar cada site → pagava token de API por site.
Depois: a API só enfileira o job; um worker desktop roda claude -p (CLI) no plano do user e devolve o HTML. Custo de geração = zero (plano, não API).
Mobile ──scan──▶ API (vision+serp+enrich) ──POST /sites──▶ job 'queued'
│
Worker desktop (sua máquina) ──GET /jobs/next──▶ claim+lock ──┘
│ claude -p <prompt> (stream-json, seu plano, cwd isolado)
└─POST /jobs/:id/{progress,complete,fail}──▶ API publica em /s/<id> + broadcast SSE
A inteligência de design vive no prompt (apps/api/src/lib/website.ts → buildPrompt(),
incorpora a skill frontend-design da Anthropic: identidade distinta, ancorada no negócio,
anti-template). O worker só executa.
Endpoints worker na API (apps/api/src/index.ts)
Gated por header x-worker-token (= env WORKER_TOKEN; vazio = aberto).
GET /jobs/next→ 204 (fila vazia) |{ id, model, prompt }(claim + marcarunningviaclaimNextJob())POST /jobs/:id/progress{ pct?, step?, logLine? }→ vira SSEsite:updatePOST /jobs/:id/complete{ html }→ escrevedata/sites/:id/index.html, statusdone, url/s/:idPOST /jobs/:id/fail{ error }
POST /sites { scanId } agora só enfileira (não dispara mais o agente). Feed via GET /events (SSE: scan:new, site:update) + GET /sites.
Extra: vision.ts/types.ts ganharam visualVibe (cores/atmosfera da fachada) que entra no prompt como referência real de paleta.
🖥️ apps/worker — worker + app desktop
Núcleo compartilhado, dois jeitos de rodar:
runner.ts—WorkerController(start/stop + estado observável). Rodaclaude -pcom--output-format stream-json --include-partial-messages --verbose --strict-mcp-config
(zero MCP servers = startup limpo), acumula sótext_delta→ progresso ao vivo (pct sobe com bytes de HTML). cwd isolado (tmpdir/facade-scout-worker) pra não carregar CLAUDE.md/skills global.worker.ts— CLI headless (bun run worker).app.ts+ui.html— app desktop: servidor Bun (porta4123) serve dashboard dark
numa janela Edge/Chrome--app(cara de app nativo, sem toolchain novo). Toggle Start/Stop,
stats (na fila/gerados/falhas), progresso do job atual + log, e feed de todas as gerações
(mesmo SSE/eventsda API). Endpoints locais/api/{status,start,stop,quit}+ SSE/api/status/stream.EADDRINUSE→ app já rodando, só foca a janela.DESKTOP_NO_OPEN=1roda headless.Scout Worker.cmd+install-shortcut.ps1— duplo-clique / atalho na área de trabalho.
Como rodar (na máquina do user)
cd C:\Users\User\facade-scout\apps\worker
copy .env.example .env # SCOUT_API já = prod; WORKER_TOKEN se a API usar
powershell -ExecutionPolicy Bypass -File install-shortcut.ps1 # 1x → atalho no Desktop
# depois: duplo-clique "Facade Scout Worker" → janela abre → "Iniciar worker"
Pré-req: bun + claude CLI logado no plano (claude --version responde).
Env (apps/worker/.env)
SCOUT_API (default prod) · WORKER_TOKEN (= o da API) · POLL_MS (4000) ·CLAUDE_MODEL (força modelo; claude-haiku-4-5-20251001 = ~80s/site vs sonnet ~2min) ·DESKTOP_PORT (4123) · DESKTOP_NO_OPEN.
✅ Estado & pendências (2026-06-27)
- API com fila + endpoints worker deployada em prod (CI verde).
/jobs/nextresponde 204. - Worker + app desktop validados e2e local: enqueue → claim → pct 12→95 → done →
/s/:idserve; start/stop/SSE ok; UI screenshotada. - ⚠️ Segurança:
/jobs/*em prod está aberto (WORKER_TOKENvazio). Só entrega prompts (sem secrets) e/scansegue token-gated, mas qualquer um pode drenar a fila. Pra fechar: setarWORKER_TOKEN=<secret>no VPSdeploy/api.env(restart API) + mesmo valor noapps/worker/.env. - Modelo default =
claude-sonnet-4-6(~2min/site). Configurável por job (AgentConfig.model) ou override no worker.
Commits-chave (branch main)
353f342feat(worker): offload site-gen to desktopclaude -pworker (zero API cost)9786878chore: update bun.lock for apps/worker workspace (fix CI frozen-lockfile)3bd5724feat(worker): desktop app — start/stop button + live generation status
Relacionado: infra/vps-hermes · projects/kodama-solutions/index