How Uai works.

Six pieces fit together: a chat, a crew, a container, an editor, a preview, and your own credentials. The architecture, in the order you'll meet it.

1. The chat loop

A task is a Slack-style channel with a goal. You set a global context for the task; each agent gets its own kickoff prompt; any agent with a non-empty kickoff opens the first turn the moment its container is ready.

Mention @agent-id to address one directly. The orchestrator routes the message; the agent answers in-channel. No hidden side conversations.

screen: a task chat with two agents trading messages

2. The crew

Each task carries a materialised agents[] array. Each entry is { id, label, kind, model?, defaultPrompt?, initialPrompt? }. id is user-chosen and unique within the task — so two kind: "claude" agents can coexist as @architect and @implementor.

Roster templates let you save crew combinations and reuse them. The host advertises which agent kinds and models it supports; the picker filters by what's actually available.

screen: roster editor with three Claudes + one Codex

3. The container

Every task runs in a fresh Docker stack named task-<id>. For each selected project Uai creates a git worktree on the task's branch and bind-mounts it into the container.

One standard image per host carries the agent CLIs and a runtime base; per-folder versions come from each repo's .tool-versions via asdf. Your main workspace is never touched.

screen: docker compose ps showing parallel task-* stacks

4. The editor

Every task container runs code-server — the same VS Code engine you know. The task page shows it in an Editor pane alongside the chat; both point at the same worktree.

Edit a file mid-conversation. Drop a debugger. Run a command in the integrated terminal. The agents see your edits the moment they read the file again.

screen: chat on the left, code-server on the right, same task

5. The preview

Declare a preview port on the project (e.g. web → 3000). Every task gets a subdomain URL like <taskId>-web.preview.runuai.com that proxies straight into the running dev server inside the container.

Hot reload works because it's a real dev server. The URL is gated by a signed cookie scoped to your account — share it across your own devices, not the internet.

screen: phone showing live preview while desktop shows the task

6. The credentials

Every task carries the task-creator's own credentials, not the host operator's. The host generates a per-user SSH keypair (you paste the public key into GitHub once) and stores the private key encrypted with the host master key.

GitHub uses the Uai App with user-to-server tokens, so every PR opened and every comment posted attributes to you, not to a bot. Tokens live in the container's ~/.config/gh/hosts.yml; the host refreshes them before each 8-hour expiry.

screen: PR on github.com authored by the actual user
Try it Self-host