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:
| Route | Method | Description |
|---|---|---|
/goals | GET | List all goals |
/goals | POST | Create a new goal |
/goals/:id/plan | GET | Retrieve execution plan |
/memory | GET | Search memory store |
/tools | GET | List registered tools |
/health | GET | Server 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:
| Mode | Behavior |
|---|---|
ALLOW | All operations permitted |
DENY | All operations blocked |
REQUIRE_APPROVAL | Operations 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 commandsread_file— read file contentswrite_file— create/overwrite filessearch_files— grep/find operationsplan— generate execution plansreview— code review operationsdelegate_task— spawn subagentsmemory— read/write memory store
Execution Plane
Three runners handle different execution contexts:
| Runner | Description |
|---|---|
| Shell Runner | Executes shell commands with stdout/stderr capture, timeout enforcement, and status reporting |
| CI/CD Runner | Dispatches GitHub Actions workflows with configurable event types, refs, and inputs |
| Data Runner | Runs 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.mdtranslations) — 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:
| Phase | What |
|---|---|
| 0 | Architecture documentation, ADR framework, bilingual setup |
| 1 | Control Plane MVP — API Gateway, Orchestrator, Planner, Policy Engine, Tools Registry |
| 2 | Execution Plane MVP — Shell, CI/CD, Data runners with orchestration |
| 3 | Memory Layer — abstract IMemoryStore interface, in-memory + SQLite implementations |
| 4 | Persistent SQLite memory — better-sqlite3 integration, schema design |
| 5 | Dashboard — SPA with WebSocket real-time feed, goal management UI |
| 6 | CLI tooling — cas command with Commander.js, partial ID resolution |
| 7 | e2e 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.