CaS — CLI as a Service: Una Arquitectura de Referencia Ejecutable para Sistemas de Agentes Autónomos

Hace unos meses empecé a preguntarme: ¿qué se necesita realmente para construir una plataforma de agentes autónomos desde cero, lista para producción? No un wrapper de chatbot o un proxy de API — sino un sistema donde agentes reales ejecutan comandos reales, orquestados por una máquina de estados, controlados por políticas y respaldados por memoria persistente.

La respuesta es CaS — CLI as a Service: una arquitectura de referencia totalmente implementada y ejecutable construida en TypeScript/NestJS. 136 tests, 8 fases, cero compromisos.


La Visión

La mayoría de las “plataformas de agentes” actuales son chatbots que generan texto. CaS fue diseñado para algo diferente: agentes que actúan — leen archivos, ejecutan comandos shell, lanzan GitHub Actions, procesan datos — todo dentro de un runtime controlado, auditado y gobernado por políticas.

Inspirado en Codex CLI y los agentes de desarrollo modernos, CaS permite que los agentes operen directamente sobre la infraestructura con niveles de autonomía configurables, manteniendo seguridad, trazabilidad y controles empresariales.


Arquitectura General

CaS está dividido en tres planos:

┌─────────────────────────────────────────────┐
│              Control Plane                   │
│  API Gateway │ Orchestrator │ Planner        │
│  Policy Engine │ Tools Registry │ PlanStore  │
├─────────────────────────────────────────────┤
│             Execution Plane                   │
│  Shell Runner │ CI/CD Runner │ Data Runner   │
│  RunnerRegistry │ RunnerOrchestrator        │
├─────────────────────────────────────────────┤
│              Memory Layer                    │
│  InMemoryStore (default) │ SQLite (driver)   │
└─────────────────────────────────────────────┘

Todo el proyecto se construyó con mi flujo Spec-Driven Development (SDD) — un proceso estructurado con fases de exploración, especificación, diseño, implementación y verificación, cada una documentada como ADRs.


Control Plane

API Gateway

Servidor REST + WebSocket en :3000. Rutas principales:

RutaMétodoDescripción
/goalsGETListar todos los objetivos
/goalsPOSTCrear un nuevo objetivo
/goals/:id/planGETObtener plan de ejecución
/memoryGETBuscar en memoria
/toolsGETListar herramientas registradas
/healthGETHealth check del servidor

Los eventos WebSocket (goal.created, goal.planned, goal.completed, goal.failed) mantienen a los clientes sincronizados en tiempo real.

Orchestrator

Una máquina de estados que gestiona el ciclo de vida de los Goals:

created → planned → running → completed
                            ↘ failed

Cada transición emite eventos WebSocket y persiste en el PlanStore. El orquestador es el sistema nervioso central — recibe comandos de la API, coordina con el planner y despacha trabajo al Execution Plane.

Planner

Planificador basado en templates que crea planes de ejecución con pasos y mapeo de herramientas. Dada una descripción de objetivo, produce un plan estructurado que el orquestador puede ejecutar de forma determinista.

Policy Engine

Sistema de autorización de tres modos, configurado via la variable POLICY_MODE:

ModoComportamiento
ALLOWTodas las operaciones permitidas
DENYTodas las operaciones bloqueadas
REQUIRE_APPROVALOperaciones requieren aprobación explícita

Esta es la capa de enforcement que separa a CaS de un simple ejecutor de scripts — guardrails de nivel empresarial sin sacrificar flexibilidad.

Tools Registry

8 herramientas seed, cada una con esquema, versionado y declaración de capacidades:

  • shell — ejecutar comandos shell
  • read_file — leer archivos
  • write_file — crear/sobrescribir archivos
  • search_files — operaciones grep/find
  • plan — generar planes de ejecución
  • review — operaciones de code review
  • delegate_task — lanzar subagentes
  • memory — leer/escribir en el store de memoria

Execution Plane

Tres runners para diferentes contextos de ejecución:

RunnerDescripción
Shell RunnerEjecuta comandos shell con captura de stdout/stderr, timeout y reporte de estado
CI/CD RunnerDispara workflows de GitHub Actions con tipos de evento, refs e inputs configurables
Data RunnerEjecuta scripts Python de procesamiento de datos con captura de stdout y propagación de errores

El RunnerRegistry gestiona el descubrimiento de runners, y el RunnerOrchestrator coordina la ejecución con lógica de reintento, asegurando aislamiento entre cargas de trabajo.


Memory Layer

Implementación dual via el token DI MEMORY_STORE:

In-Memory (default): respaldado por Map, efímero. Perfecto para desarrollo y tests — cero configuración, reset instantáneo.

SQLite (MEMORY_DRIVER=sqlite): respaldado por better-sqlite3, persistente entre reinicios. Almacena registros de objetivos completados y provee inyección de contexto para los planners.

Este diseño hace trivial intercambiar backends de almacenamiento sin tocar la lógica de negocio — un patrón clásico de Inyección de Dependencias que NestJS maneja elegantemente.


Dashboard

Un SPA con tema oscuro servido en http://localhost:3000/ con:

  • Feed de objetivos en tiempo real via WebSocket (Socket.IO)
  • Creación y seguimiento de objetivos
  • Visualización de planes
  • Búsqueda en memoria
  • Conexión directa al API Gateway

El dashboard prueba que el sistema funciona end-to-end y provee un feedback loop visual durante el desarrollo.


CLI: El Comando cas

Un CLI con Commander.js + Chalk con 7 comandos:

cas health              # Ver estado del servidor
cas goals list          # Listar objetivos
cas goals get <id>      # Ver detalle de objetivo (resolución parcial)
cas goals create <desc> # Crear nuevo objetivo
cas goals plan <id>     # Generar plan para un objetivo
cas tools               # Listar herramientas
cas memory <query>      # Buscar en memoria

La resolución parcial de IDs es un detalle interesante — cas goals get abc encuentra el primer objetivo que empieza con abc, evitando tener que escribir UUIDs completos.

El CLI se publica como packages/cas-cli en el monorepo, instalable con un alias shell.


Stats & Testing

  • Fases: 8 (0 a la 7), construidas con SDD workflow
  • Tests: 136 pasando — tests unitarios para cada servicio, e2e para el API Gateway
  • Archivos fuente: 40+ archivos TypeScript en el monorepo
  • Docs: Bilingües (EN principal, traducciones .es.md) — 7 docs de arquitectura + notas de investigación
  • ADRs: Architecture Decision Records documentando cada decisión de diseño importante
  • Build: TypeScript + tsup, monorepo NestJS con pnpm workspaces

El Viaje SDD

CaS se construyó con el flujo Spec-Driven Development, fase por fase:

FaseQué se hizo
0Documentación de arquitectura, framework ADR, setup bilingüe
1Control Plane MVP — API Gateway, Orchestrator, Planner, Policy Engine, Tools Registry
2Execution Plane MVP — Shell, CI/CD, Data runners con orquestación
3Memory Layer — interfaz abstracta IMemoryStore, impls in-memory + SQLite
4Memoria SQLite persistente — integración better-sqlite3, diseño de esquema
5Dashboard — SPA con WebSocket en tiempo real, UI de gestión de objetivos
6CLI tooling — comando cas con Commander.js, resolución parcial de IDs
7Cobertura e2e + estabilización — 136 tests, overhaul del README

Cada fase incluyó un Judgment Day donde evaluaba si la arquitectura seguía siendo sólida antes de continuar.


Probarlo

git clone https://github.com/fxckcode/CaS.git
cd CaS/src/control-plane
pnpm install
pnpm build && node dist/main.js
# → Servidor en http://localhost:3000
# → Dashboard en http://localhost:3000/

# Memoria persistente (opcional)
MEMORY_DRIVER=sqlite node dist/main.js

# Ejecutar tests
pnpm test  # 136 tests, 0 failures

# CLI (desde otra terminal)
cas health
cas goals create "Desplegar API v3"

El proyecto tiene licencia MIT y está disponible en GitHub. Ya sea que estés construyendo una plataforma de agentes para tu equipo o simplemente tengas curiosidad sobre cómo funcionan estos sistemas internamente, el código está ahí para leerlo, ejecutarlo y forkearlo.

Compartir
D
Diego Duran
@fxckcode

Ingeniero backend que construye herramientas CLI agentivas. NestJS, Go, Django, AWS.