Docs · 20
Arquitectura.
Monorepo Next.js + worker, Anthropic Managed Agents, Supabase Postgres + Storage. Cómo se hablan.
El monorepo
Codacle es un monorepo PNPM con tres paquetes principales:
| Paquete | Qué hace |
|---|---|
apps/web | Next.js 15 App Router. UI completa + server actions + scripts CLI (register-kit, cost-report, inspect-run, etc.). |
apps/worker | Servicio long-running que consume jobs de Supabase y orquesta a Anthropic Managed Agents. |
packages/db | Supabase client (supabaseAdmin()), Zod schemas para entidades compartidas, helpers de pricing (costUsd, PRICING_PER_MTOK). |
El flujo end-to-end
[user] [next.js] [supabase] [worker] [anthropic]
│ │ │ │ │
├─ crea ws ───────►│ │ │ │
│ ├─ INSERT workspace ─►│ │ │
│ ├─ INSERT job analyze►│ │ │
│ │ │◄─ poll jobs ───────┤ │
│ │ │ ├─ create session ───►│
│ │ │ │◄── stream events ───┤
│ │ │ ├─ write vault_atoms ─┤
│ │ │◄─ UPDATE ws.status─┤ │
│◄ revalidatePath ─┤ │ │ │
Resumido:
- El user crea un workspace desde el marketplace.
- Next.js (server action
createWorkspaceAndStart) inserta la row enworkspacesy encola unjobtipoanalyze. - El worker polleea
jobs(interval corto), toma el job pendiente, abre una session en Anthropic, manda el agente del kit pinneado al workspace. - El agente emite eventos (
tool_use,text,report_phase,emit_atom). El worker traduce:emit_atom→ INSERT envault_atoms,report_phase→ UPDATE enworkspace_phases, etc. - Cuando el agente cierra, el worker actualiza
workspace.status. La UI hace polling de/api/workspaces/[id]/ops-stateophasesy refresca live.
La tabla kits
Una row por (kit_id, version). El manifest (jsonb) tiene todo: agentes, skills, inputs, fases, tabs habilitadas, modelos a usar. Cuando registrás un kit con register-kit, la CLI:
- Lee el directorio del kit (
<kit_dir>/manifest.yaml+ skill files + agent definitions). - Valida contra el schema Zod (
apps/worker/src/lib/kit-manifest-schema.ts). - Sube cada skill a Anthropic — devuelve un
skl_...ID. Los guarda en el jsonbskill_ids. - Crea un environment compartido —
env_.... Lo guarda en columna propia (environment_id). - Crea cada agent referenciando ese environment + skills —
agent_.... Los guarda enagent_ids. - Upsertea la row en
kitscon todos esos IDs.
kit_publications apunta a una versión concreta — workspaces nuevos usan esa. Cambiar de versión publicada es la operación de rollback / upgrade.
El worker en detalle
apps/worker/src/index.ts corre un loop que:
- Polleea
SELECT * FROM jobs WHERE status='queued' LIMIT 1 FOR UPDATE SKIP LOCKED(Postgres lock evita doble proceso). - Despacha al handler según
job.type:analyze,map,migrate,kit_run. - Cada handler abre una
Sessionen Anthropic Managed Agents y stream-consumea sus eventos. - Custom tools del agente (declarados en el kit) son dispatched por el worker —
read_file,write_atom,report_phase,emit_output, etc. Las respuestas vuelven al agent porstop_reason.event_ids. - Al cerrar la session: persiste
usage+pricing_snapshotenworkspace_runspara tener telemetría retroactiva estable cuando Anthropic cambie rates.
Telemetría y observabilidad
workspace_runs— una row por cada vez que el worker procesa un job. Tiene Anthropic IDs (session_id,agent_id,environment_id,memory_store_id),usage,duration_ms,status,pricing_snapshot. Base para/ops,/ops/[id],/ops/trends,/ops/errors, y el costo del/overview.workspace_phases— el estado granular por fase. Lo escribe el worker al recibirreport_phaseevents./migrations/[id]/pipelinelee esto live.vault_atoms— los entities extraídos./migrations/[id]/vaultlo navega.messages— conversación de Barbara (el chat assistant). Persistido para context across sessions.
Caching
Server-side, usamos unstable_cache de Next con TTL cortas (30s) en lecturas que se pueden volver hot bajo polling — /ops/resources (Anthropic API) y listKitsCatalog son los principales. El catálogo de kits cambia raras veces; no hace falta golpear Supabase en cada request del marketplace.
revalidatePath se llama explícitamente desde los server actions que mutan datos relevantes (publishKitVersion, unpublishKit, createWorkspaceAndStart).