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 in frontend/src/App.tsx.
  • backend (backend/) – an Express‑style service written in TypeScript and C/C++ bindings. The main server starts from backend/index.ts; the agents‑server CLI lives under backend/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 is moonlight-fork/moonlight-web/web-server/web/stream/pipeline/index.ts.
  • dashboard – a small React admin panel (dashboard/src/App.tsx) that reads the same .env files 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

  1. Start point – backend/agents-server/src/ariana-cli/index.ts defines main (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.
  1. Core orchestration – main calls findMany on the Prisma client (this.prisma.agent.findMany), which reads the agent table (242 functions in the repo touch a DB). The result seeds the in‑memory AgentGlobalState.
  1. WebSocket bridge – backend/src/websocket/server.ts creates a WebSocket server (onMessage → sendError → ws.send). This is the only outbound network call outside the DB path.
  1. Streaming pipeline – The UI‑side addHost (in moonlight-fork/moonlight-web/web-server/web/index.ts) creates a host, which triggers apiPostHost → fetchApi → a Prisma deleteMany on agent. The pipeline (pipeline/index.ts) is a hub module with 27 inbound and 15 outbound imports; it sits in a circular dependency with agentsState.ts and pipes.ts.
  1. Shared services – backend/src/utils/logger.ts is a pure hub (30 callers, 0 imports) and backend/agents-server/src/cryptoSingleton.ts is the most depended‑on crypto module (43 callers, 1 import). Changes here have the highest blast radius.
  1. 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/*.yml uses 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:. Add contents: read.
  • Medium – Enable Dependabot – No dependabot.yml despite 17 manifest files.
  • Medium – Pin Docker base images – Use digests for node:20-slim and oven/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.mp4 and several images >5 MiB; move to Git LFS or external storage.
  • Medium – Checkout persist‑credentials – Set persist-credentials: false in 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.