CaS — CLI as a Service: An Executable Reference Architecture for Autonomous Agent Systems

A few months ago I started wondering: what does it actually take to build a production-grade autonomous agent platform from scratch? Not a chatbot wrapper or an API proxy — but a system where real agents execute real commands, orchestrated by a state machine, gated by policies, and backed by persistent memory.

The answer is CaS — CLI as a Service: a fully implemented, executable reference architecture built in TypeScript/NestJS. 136 tests, 8 phases, zero compromises.


The Vision

Most of today’s “agent platforms” are chatbots that generate text. CaS was designed for something different: agents that act — read files, run shell commands, dispatch GitHub Actions, process data — all inside a controlled, auditable, policy-governed runtime.

Inspired by Codex CLI and modern development agents, CaS lets agents operate directly on infrastructure with configurable autonomy levels, while maintaining security, audit trails, and enterprise policy controls.


Architecture Overview

CaS is split into three planes:

┌─────────────────────────────────────────────┐
│               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)   │
└─────────────────────────────────────────────┘

The entire project was built using my Spec-Driven Development (SDD) workflow — a structured process with exploration, specification, design, implementation, and verification phases, each documented as ADRs.


Control Plane

API Gateway

REST + WebSocket server on :3000. Routes include:

RouteMethodDescription
/goalsGETList all goals
/goalsPOSTCreate a new goal
/goals/:id/planGETRetrieve execution plan
/memoryGETSearch memory store
/toolsGETList registered tools
/healthGETServer health check

WebSocket events (goal.created, goal.planned, goal.completed, goal.failed) keep connected clients in sync in real time.

Orchestrator

A state machine managing the Goal lifecycle:

created → planned → running → completed
                            ↘ failed

Each transition emits WebSocket events and persists to the PlanStore. The orchestrator is the central nervous system — it receives commands from the API, coordinates with the planner, and dispatches work to the Execution Plane.

Planner

Template-based planner that creates execution plans with steps and tool mappings. Given a goal description, it produces a structured plan that the orchestrator can execute deterministically.

Policy Engine

Three-mode authorization system, configured via POLICY_MODE env var:

ModeBehavior
ALLOWAll operations permitted
DENYAll operations blocked
REQUIRE_APPROVALOperations require explicit approval

This is the enforcement layer that separates CaS from a simple script runner — enterprise-grade guardrails without sacrificing flexibility.

Tools Registry

8 seed tools, each with schema, versioning, and capability declarations:

  • shell — execute shell commands
  • read_file — read file contents
  • write_file — create/overwrite files
  • search_files — grep/find operations
  • plan — generate execution plans
  • review — code review operations
  • delegate_task — spawn subagents
  • memory — read/write memory store

Execution Plane

Three runners handle different execution contexts:

RunnerDescription
Shell RunnerExecutes shell commands with stdout/stderr capture, timeout enforcement, and status reporting
CI/CD RunnerDispatches GitHub Actions workflows with configurable event types, refs, and inputs
Data RunnerRuns Python data processing scripts with stdout capture and error propagation

The RunnerRegistry manages runner discovery, and the RunnerOrchestrator coordinates execution with retry logic, ensuring fault isolation between workloads.


Memory Layer

Dual implementation via the MEMORY_STORE DI token:

In-Memory (default): Map-backed, ephemeral. Perfect for development and testing — zero setup, instant reset.

SQLite (MEMORY_DRIVER=sqlite): better-sqlite3-backed, persistent across restarts. Stores goal completion records and provides context injection for planners.

This design makes it trivial to swap storage backends without touching business logic — a classic Dependency Injection pattern that NestJS handles elegantly.


Dashboard

A dark-themed SPA served at http://localhost:3000/ with:

  • Real-time goal feed via WebSocket (Socket.IO)
  • Goal creation and status tracking
  • Plan visualization
  • Memory search
  • Connects directly to the API Gateway

The dashboard proves the system works end-to-end and provides a visual feedback loop during development.


CLI: The cas Command

A Commander.js + Chalk CLI tool with 7 commands:

cas health              # Check server status
cas goals list          # List all goals
cas goals get <id>      # Get goal by ID (partial ID resolution)
cas goals create <desc> # Create a new goal
cas goals plan <id>     # Generate a plan for a goal
cas tools               # List available tools
cas memory <query>      # Search memory store

Partial ID resolution is a nice touch — cas goals get abc matches the first goal starting with abc, so you don’t need full UUIDs.

The CLI is published as packages/cas-cli in the monorepo, installable with a shell alias.


Stats & Testing

  • Phases: 8 (0 through 7), built with SDD workflow
  • Tests: 136 passing — unit tests for every service, e2e tests for the API Gateway
  • Source files: 40+ TypeScript files across the monorepo
  • Docs: Bilingual (EN primary, .es.md translations) — 7 architecture docs + research notes
  • ADRs: Architecture Decision Records documenting every major design choice
  • Build: TypeScript + tsup, NestJS monorepo with pnpm workspaces

The SDD Journey

CaS was built using the Spec-Driven Development workflow, phase by phase:

PhaseWhat
0Architecture documentation, ADR framework, bilingual setup
1Control Plane MVP — API Gateway, Orchestrator, Planner, Policy Engine, Tools Registry
2Execution Plane MVP — Shell, CI/CD, Data runners with orchestration
3Memory Layer — abstract IMemoryStore interface, in-memory + SQLite implementations
4Persistent SQLite memory — better-sqlite3 integration, schema design
5Dashboard — SPA with WebSocket real-time feed, goal management UI
6CLI tooling — cas command with Commander.js, partial ID resolution
7e2e coverage + stabilization — 136 tests, README overhaul

Each phase included a Judgment Day review where I assessed whether the architecture was still sound before proceeding.


Try It

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

# Enable persistent memory (optional)
MEMORY_DRIVER=sqlite node dist/main.js

# Run tests
pnpm test  # 136 tests, 0 failures

# CLI (from another terminal)
cas health
cas goals create "Deploy API v3"

The project is MIT licensed and available on GitHub. Whether you’re building an agent platform for your team or just curious about how these systems work under the hood, the code is there to read, run, and fork.

Share
D
Diego Duran
@fxckcode

Backend engineer who ships agentic CLI tooling. NestJS, Go, Django, AWS.