
**English** · [繁體中文](./README.zh-TW.md)
# LazyBoy
**Give AI a computer so it can do the work.**
A self-hosted AI agent workspace. Assign tasks in text or voice, watch the desktop live, and take over whenever you need to.
[Quick start](#quick-start) · [Features](#features) · [Architecture](./docs/architecture.md) · [Operations](./docs/operations.md) · [Development](./docs/development.md)

LazyBoy gives each agent its own Linux desktop in Docker — browser, terminal, and files. You can run several agents, put them in a group, turn a demonstration into a skill, and schedule it to run again.
This is an early `v0.1.0-alpha` release with desktop and phone browser UIs. Every person registers their own account, and model API keys live in the app's settings rather than in the environment.
## Features
- **One account per person**: register a username and password, and the whole workspace — agents, chats, credentials, model keys — belongs to that account alone.
- **A lasting workspace**: each agent has its own chats, run history, and optional long-term memory.
- **A real computer**: open pages, use the terminal, organize files, drive the GUI — and watch it live.
- **Attachments in chat**: send files or images along with the message; the agent can open them on its own desktop, and inbox copies expire on their own.
- **Take over any time**: sign in, pass a check, or nudge things by hand on the same desktop, then hand it back.
- **Saved logins**: keep site credentials in the agent's encrypted vault, so it can fill them in at a login wall without the password ever passing through the model.
- **Several agents and groups**: shared Team computers or private dedicated desktops; `@name` decides who answers, so a message wakes the one agent it is for instead of all of them.
- **Teach by demo, then schedule**: turn a walkthrough into a skill; use cron for repeat work.
- **Your models and tools**: xAI, OpenCode Go, OpenAI-compatible endpoints, MCP, and file skills.
- **Voice calls**: after you enable a voice provider, you can talk to the agent on a call.
- **Phone-friendly**: collapse the chat sidebar; the remote desktop has keyboard, trackpad, right-click, drag, and scroll.
- **English and Traditional Chinese**: switch the UI language in the app.
## Quick start
You need Docker and Compose, Git, Make, and Python 3, plus an API key for a supported model — you paste that key into the app after you register, not into `.env`. On macOS use Docker Desktop or OrbStack; on Linux use Docker Engine.
From the repo root:
```bash
make env
```
The generated `.env` holds service secrets only (supervisor, credential vault, database); the init tool fills them in and keeps existing values when run again. Nothing about signing in or model access is configured here.
```bash
make up
make health
```
Open **[http://127.0.0.1:3101](http://127.0.0.1:3101)**, register an account with any username and password you like, paste your model API key under **Settings → Models**, then create an agent and pick a model. Without a key nothing runs — the app tells you where to add one.
The first run builds the API and Linux desktop images from source and takes a while. The build toolchain lives in the containers, so a full Docker deploy does not need Rust or Node.js on the host.
Try a concrete task:
> Open the site I name, summarize the page, and save the notes as a Markdown file in the workspace.
Status and logs:
```bash
make ps
make logs
make down # stop services, keep PostgreSQL data
```
For resource limits, environment variables, HTTPS, and in-container sudo, see [Operations](./docs/operations.md).
## On a phone
Desktop and phone share the same web UI. The API listens on `127.0.0.1` by default, so set `LAZYBOY_BIND_IP=0.0.0.0` (or one network card's address) in `.env` and recreate the api container before a phone on your network can reach it. Then open that address in the phone browser — `127.0.0.1` there is the phone itself and will not reach another machine — and register there too: two people on one install each see only their own agents. Reaching the app by a domain name instead of an IP or `localhost` additionally requires listing it in `LAZYBOY_ALLOWED_HOSTS`.
Tap outside the chat sidebar to collapse it. On the remote desktop you can switch between tap-to-click and trackpad, and use the toolbar for keyboard, right-click, or drag. Put the service behind HTTPS before you expose it; see [Operations](./docs/operations.md#安全模型).
## Stack
- **Frontend**: React 19, TypeScript, Vite, noVNC
- **Backend**: Rust 2024, Axum, Tokio
- **Data**: PostgreSQL, pgvector, SQLx
- **Desktop**: Docker, Debian, XFCE, Chromium, Xvfb
- **Computer control**: Cua Driver over X11, AT-SPI, and Chromium
- **Extensions**: MCP, file skills, demonstration playbooks
Flow diagrams, handoff, component roles, and the computer lifecycle live in **[Architecture](./docs/architecture.md)**. The older **[interactive diagram](./docs/workflow.html)** is still there — download it and open it in a browser.
## Local development
Besides Docker, you need a Rust toolchain that supports the 2024 edition, plus Node.js / npm.
```bash
make dev
make dev-supervisor # terminal 1
make dev-api # terminal 2
```
Frontend hot reload in another terminal:
```bash
cd apps/web
npm install
npm run dev
```
Open [http://127.0.0.1:5173](http://127.0.0.1:5173). Tests and the tree layout are in the [development guide](./docs/development.md).
## Docs
The guides below are currently in Traditional Chinese.
| Doc | Contents |
| -------------------------------------------------------- | ---------------------------------------------------- |
| [Architecture](./docs/architecture.md) | Task flow, system architecture, computer lifecycle |
| [Interactive diagram](./docs/workflow.html) | Zoomable, searchable HTML chart; download and open |
| [Operations](./docs/operations.md) | Resources, env vars, security, site checks, sudo |
| [Agent experience](./docs/agent-experience.md) | Turn limits, persistent terminal, live chat |
| [hermes-agent review](./docs/hermes-agent-cua-review.md) | Cua harness smoothness: comparison with hermes-agent |
| [Development](./docs/development.md) | Local dev, checks and tests, directory layout |
| [Env example](./.env.example) | Environment variables and defaults |
## Data
Chats, memory, browser profiles, and encrypted credentials stay on your host. When you use an external model, the prompts, tool results, and screenshots the task needs may still be sent to that provider.
## Acknowledgements
LazyBoy is mostly other people's software, carefully assembled. The projects we lean on hardest:
**Special thanks**
- **[Cua](https://github.com/trycua/cua)** — the Linux desktop driver behind every click, keystroke, and screenshot. We rebuild `cua-driver-rs` v0.23.2 from source with two small patches kept in this repo: one lets the agent cursor wear the bot's own colour, the other swaps the embedded Latin-only badge font for [jf open Huninn](https://github.com/justfont/open-huninn-font) so Chinese renders. Neither patch touches input handling or permissions.
- **[hermes-agent](https://github.com/NousResearch/hermes-agent)** — not a dependency, but the reference we kept returning to while tuning how smooth an agent's desktop should feel. The comparison is written up in the [hermes-agent review](./docs/hermes-agent-cua-review.md).
**Agents and retrieval** — [rig](https://github.com/0xPlaygrounds/rig) · [rmcp](https://github.com/modelcontextprotocol/rust-sdk) · [fastembed-rs](https://github.com/Anush008/fastembed-rs) and [ONNX Runtime](https://github.com/microsoft/onnxruntime), running [paraphrase-multilingual-MiniLM-L12-v2](https://huggingface.co/sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2)
**Rust** — Tokio · Axum · tower-http · SQLx · reqwest · rustls · Bollard · tracing · aes-gcm and hmac from [RustCrypto](https://github.com/RustCrypto) · cap-std · cron · chrono · uuid · thiserror · dotenvy
**Web** — React · Vite · TypeScript · [noVNC](https://github.com/novnc/noVNC) · react-markdown with [remark-gfm](https://github.com/remarkjs/remark-gfm) and [remark-breaks](https://github.com/remarkjs/remark-breaks) · [Blobatar](https://github.com/Alain00/blobatar) avatars · [react-useanimations](https://github.com/useAnimations/react-useanimations) icons
**Data** — [PostgreSQL](https://www.postgresql.org) · [pgvector](https://github.com/pgvector/pgvector)
**The desktop inside each container** — [Docker](https://www.docker.com) · [Debian](https://www.debian.org) · [XFCE](https://www.xfce.org) · [Chromium](https://www.chromium.org) · [Xvfb](https://www.x.org) · Thunar · [x11vnc](https://github.com/LibVNC/x11vnc) · [websockify](https://github.com/novnc/websockify) · [AT-SPI2](https://gitlab.gnome.org/GNOME/at-spi2-core) · [gosu](https://github.com/tianon/gosu) · [LXCFS](https://github.com/lxc/lxcfs) · git · zsh with [Powerlevel10k](https://github.com/romkatv/powerlevel10k) · htop
**Type and theme** — [jf open Huninn](https://github.com/justfont/open-huninn-font) (SIL OFL) in the UI and on the agent badge · [Noto CJK](https://github.com/notofonts/noto-cjk), DejaVu, and Liberation as fallbacks · [MesloLGS NF](https://github.com/romkatv/powerlevel10k-media) in the terminal · [Arc Dark](https://github.com/horst3180/arc-theme) and [Papirus](https://github.com/PapirusDevelopmentTeam/papirus-icon-theme) for the look of the room
Every version above is pinned in `Cargo.lock`, `apps/web/package.json`, and `image/computer/Dockerfile`. LazyBoy is Apache-2.0; each project keeps its own license. Thanks also to the maintainers whose names never make it into a README, and to everyone who files a good bug report.
---