The Problem
Developers need a self‑hosted platform that can run autonomous coding agents, manage GitHub repos, spawn Docker containers, and stream a desktop‑grade UI. Existing SaaS solutions lock you into proprietary back‑ends and expose secrets when the UI is hosted publicly.
What This Does
ariana stitches together four independent projects:
- frontend (
frontend/) – a React/Vue UI built with TypeScript/TSX, Tailwind and Docker. Entry UI components live infrontend/src/App.tsx. - backend (
backend/) – an Express‑style service written in TypeScript and C/C++ bindings. The main server starts frombackend/index.ts; the agents‑server CLI lives underbackend/agents-server/src/ariana-cli/index.ts. - moonlight‑fork – a custom Web‑RTC streaming stack (
moonlight-fork/moonlight-web/web-server/...) that delivers the “gaming‑grade” desktop view. The core pipeline ismoonlight-fork/moonlight-web/web-server/web/stream/pipeline/index.ts. - dashboard – a small React admin panel (
dashboard/src/App.tsx) that reads the same.envfiles used by the backend.
All projects share a common type layer (backend/shared/types/index.ts) and a logger (backend/src/utils/logger.ts). The backend talks to a PostgreSQL database via Prisma (see backend/src/data/repositories/*) and to the frontend through WebSocket (backend/src/websocket/server.ts).
How It Is Wired
- Start point –
backend/agents-server/src/ariana-cli/index.tsdefinesmain(line 208) and is the only function that reaches a broad sub‑graph (46 functions). It is invoked by the Docker entrypoint or by running the CLI script directly.
- Core orchestration –
maincallsfindManyon the Prisma client (this.prisma.agent.findMany), which reads theagenttable (242 functions in the repo touch a DB). The result seeds the in‑memoryAgentGlobalState.
- WebSocket bridge –
backend/src/websocket/server.tscreates a WebSocket server (onMessage→sendError→ws.send). This is the only outbound network call outside the DB path.
- Streaming pipeline – The UI‑side
addHost(inmoonlight-fork/moonlight-web/web-server/web/index.ts) creates a host, which triggersapiPostHost→fetchApi→ a PrismadeleteManyonagent. The pipeline (pipeline/index.ts) is a hub module with 27 inbound and 15 outbound imports; it sits in a circular dependency withagentsState.tsandpipes.ts.
- Shared services –
backend/src/utils/logger.tsis a pure hub (30 callers, 0 imports) andbackend/agents-server/src/cryptoSingleton.tsis the most depended‑on crypto module (43 callers, 1 import). Changes here have the highest blast radius.
- Effect ownership – DB writes:
backend/src/data/repositories/agent.repository.ts(33 functions, called from 55 files). Network I/O:backend/src/websocket/server.ts(18 functions). * Filesystem I/O:backend/src/websocket/server.ts(also writes log files).
The import graph contains 38 cycles; the most prominent is the streaming pipeline cycle, which inflates build times and makes refactoring risky.
How To Use It
# Clone the repo (use the exact URL)
git clone https://github.com/moses-y/ariana
cd ariana
# Build the Docker image (the Dockerfile pulls Node 20‑slim)
docker build -t ariana .
# Run the container, exposing the backend API and the WebSocket port
docker run -d -p 3000:3000 -p 4000:4000 \
-e DATABASE_URL=postgres://user:pass@db:5432/ariana \
ariana
Configuration – copy the examples and edit the values:
cp backend/.env.example backend/.env
cp dashboard/.env.development dashboard/.env
# edit backend/.env and dashboard/.env with your DB credentials,
# Anthropic API token, and any SSH keys required by agents.
CLI – to invoke the agents‑server directly (useful for local dev):
# install ts-node globally or via the project's package.json scripts
npx ts-node backend/agents-server/src/ariana-cli/index.ts --help
The UI is served from the container at http://localhost:3000. The dashboard is reachable at http://localhost:3000/dashboard.
Real‑World Use
A CI pipeline can spin up an ariana container, push a new git branch, and let an autonomous agent automatically run unit tests, create a Docker image, and stream the desktop UI to a reviewer. The agent writes its state to the agent table, reports progress over the WebSocket, and the dashboard visualises the live diff.
Code Health & Issues
- High – Pin GitHub Actions –
.github/workflows/*.ymluses mutable tags (@v1). Replace with commit SHAs. - High – Missing LICENSE – No license file; add MIT or Apache‑2.0.
- High – Committed secrets –
dashboard/.env.development(and production) contain live credentials; remove, add to.gitignore, rotate keys. - Medium – Least‑privilege GITHUB_TOKEN – Workflows lack explicit
permissions:. Addcontents: read. - Medium – Enable Dependabot – No
dependabot.ymldespite 17 manifest files. - Medium – Pin Docker base images – Use digests for
node:20-slimandoven/bun:1. - Medium – Add dependency‑review CI – No vulnerability scan step.
- Medium – Pre‑commit secret gate – Add a secret‑scan hook.
- Medium – Large binaries –
assets/0Zc0m3XtjJGFa_6g.mp4and several images >5 MiB; move to Git LFS or external storage. - Medium – Checkout persist‑credentials – Set
persist-credentials: falsein release workflow.
Additional findings: 16 import cycles, 13 hub modules, 23 deep‑nesting hotspots, 6 oversized files (>1 k LOC).
The Bottom Line
ariana delivers a functional, self‑hosted agent platform with a rich UI and streaming layer, but the codebase is fragmented, contains several high‑impact health issues, and suffers from circular dependencies that impede safe evolution. It is suitable for teams willing to invest in refactoring and security hardening; otherwise, the platform should be used as a reference implementation rather than production‑ready code.