How Uai works.

A chat, a crew, a container, a schedule, your credentials, and the roles that say who may do what — the architecture, in the order you'll meet it.

1The chat loop

A task is a Slack-style channel with a goal. You set the context once; each agent gets its own kickoff prompt and opens the first turn as soon as 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.

2Catching up

A busy task outruns you. Come back after lunch and the tail of the feed doesn't tell you where things stand.

So a task has two halves: the chat on the left, and one panel on the right — Activity, TLDR, Artifacts, Preview, Diff, or Code Editor, one at a time.

TLDR is the catching-up half. Artifacts indexes what the task has produced — links, files, the pull request and its diff, preview URLs — so nothing useful scrolls away.

With a subscription it also generates a Digest: where things stand, what's blocked, what's next. Every claim cites the message it came from, so you can check it against the transcript instead of trusting it — on Uai's own allowance, never your keys.

TLDR — the generated summary so far. Live while the task runs, every claim cited, not a final report.

3Personas & the crew

You don't configure agents per task — you design personas and reuse them. A persona is a named, reusable teammate with its own @handle, role and brief.

Pick its engine — currently Claude, Codex, Kimi Code, Grok, Cursor, and OpenCode — with model and effort, attach skills, and grant its permissions. Memory carries what it learned into the next task.

Group personas into Teams and drop a whole team onto a task as a unit. The agents on one task are its crew.

One agent, mid-configuration: engine, model and effort are per-agent, and skills and memory travel with it onto every task.

4Agents that plan

Point a planner persona at a goal and it drafts the backlog for you — fully-configured task and subtask drafts. Nothing runs until you press Start.

Subtasks carry the parent's chat as context and kick off when the parent closes.

Every task grouped by real status — Draft included. Nothing runs until a draft is started.

5Work that repeats

Some work isn't a one-off — a nightly dependency bump, a weekly changelog. The only missing piece is someone to click Start at 3am.

Put a task on a cron and every occurrence starts fresh — its own branch, container, and chat. A schedule owns a template task and clones it each run, so last night's mess can't bleed into tonight's. Every run is recorded.

Set it from the composer's Repeat control. Your timezone is stored alongside it, because “every day at 09:00” is a wall-clock promise, not an interval.

Cadence
Five-field cron plus an IANA timezone. One hour is the floor — five minutes would mean 288 containers a day.
Overlap, downtime, failure
A still-running occurrence is skipped, not doubled; an outage gets one catch-up run, or none, the default, instead of a backlog; five failures in a row disable the schedule rather than burn a container nightly.
Who sets one
A permission of its own, off by default: scheduling a task commits the workspace to spending again every night. See roles.
Cadence, next run, last run, and Run now — the whole story of a schedule in one row.

6The container

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

One standard image per runner carries the agent CLIs and a runtime base; per-folder versions come from each repo's .tool-versions.

7The editor

Every task container runs code-server — the same VS Code engine you know. It's the Code Editor tab of the right panel; it and the chat point at the same worktree.

Edit a file mid-conversation, drop a debugger, run a command. The agents see your edits the moment they read the file again.

8In-app review

Before anything ships, you review it. The Diff panel spans every repo in the task, comparing the task branch against your default branch — beside the conversation that produced it, not covering it up.

Approve what's right; send the rest back with a message — no leaving for "go check GitHub."

The diff sits beside the conversation that produced it — every repo in the task, unified or split.

9The preview

Declare a preview port on the repository. Every task gets a subdomain URL that proxies straight into the running dev server inside its container.

Hot reload works because it's a real dev server. By default the URL is private, gated by a signed cookie; on Dev and up you can make it public — guarded only by an unguessable task ID — to hand to a teammate.

That visibility setting belongs to the preview URL alone. The Chromium an agent drives for browser testing, next, is never published that way.

Dev-server URLs are reachable by anyone who has one — the agents' browser is never published that way. Shown made public, for illustration — private is the default.

10Browser testing

Turn on browser testing and agents get a real Chromium they drive through the Playwright MCP — navigate, click, reload, assert — against a live preview. Opt-in, per repository.

Every competitor's answer to "did the agent actually check?" is "it says it did." Ours is a URL.

The QA agent @kit reports back after testing: the theme persists across reload with no flash on first paint — and separately flags a missing focus ring as a follow-up. A tester that only ever says it passed is the weak answer.

11The credentials

Every task carries the task-creator's own credentials, not the runner operator's. The runner generates a per-user SSH keypair and keeps the private key encrypted under the runner master key, never touching your ~/.ssh. Commits are authored with your git identity.

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.

The same protection covers your AI keys. Each runner holds one or more AI Engines accounts per engine and tries them in priority order — add a second Claude account and a persona quietly keeps working when the first is rate-limited.

A pull request GitHub itself attributes to a person — no bot badge, because there isn't one to draw.
Multiple accounts per engine, in priority order — a rate-limited key falls back to the next one down the list.

12Roles & permissions

One person's workspace needs no governance. The moment it has contractors, "may this human do this?" becomes a real question — and it is not the same question as "did the workspace pay?"

So a workspace defines roles. A role carries permissions, caps, and the personas and runners it unlocks. Roles combine as a union — adding one can grant access, never take it away.

One catalog covers both audiences: the same tasks.create and tasks.start decide whether you may draft a task or start one, and whether an agent may too. Caps only ever clamp down against your plan, never up. And nothing changes on the day you turn roles on.

Admins get one power over other people's work, deliberately: they close any task in the workspace. A runaway task from someone now on holiday needs an off switch.

Same catalog for people and agents — tasks.start is the action that spends money.

More surfaces

See the whole loop in your repo.

Design a crew, start a task, and watch the whole loop come together — on a runner you control.