AutoCua
Automate with computer-use agent (ComputerUse / CUA) for macOS, Windows, Linux, Browser, iOS & Android. It sees the screen, clicks, types, browses and writes the code too. One agent, every computer.
翻译准备中
正在加载完整 README。 以下为已保存的摘录。
Website · ▶ Try it in your browser — the actual Python server on Pyodide/WASM, nothing leaves your machine.
when2meet-style scheduling polls — self-hostable, reverse-proxy-auth friendly,
agent-first API (OpenAPI + llms.txt + MCP).
or with Docker / a real database:
Dockerfile + compose.yaml in this repo — SQLite on a named volume, non-root,
no build toolchain in the runtime layer.查看完整 README ↗Website · ▶ Try it in your browser — the actual Python server on Pyodide/WASM, nothing leaves your machine.
when2meet-style scheduling polls — self-hostable, reverse-proxy-auth friendly, agent-first API (OpenAPI + llms.txt + MCP).
uvx --from kairos-scheduler kairos # SQLite + demo auth on :8003
or with Docker / a real database:
KAIROS_DB_URL=mysql://user:pass@host:3306/db \
KAIROS_AUTH=header SESSION_SECRET=$(openssl rand -hex 32) \
uvx --from 'kairos-scheduler[mysql]' kairos --host 0.0.0.0
Dockerfile + compose.yaml in this repo — SQLite on a named volume, non-root,
no build toolchain in the runtime layer.
podman compose up -d # build, run, http://127.0.0.1:8003/
podman compose logs -f kairos
The database is on the volume, so down and up keep every poll (down -v
deletes them). It publishes on loopback only and runs in demo auth, which
means one shared owner and no authentication — fine locally, never on a public
interface.
Real deployments add a TLS terminator and either Kairos-managed OIDC or an OIDC proxy in front:
cp .env.example .env && $EDITOR .env # secrets; compose refuses to start without them
podman compose -f compose.oidc.yaml up -d # Kairos is the OIDC client (no auth proxy)
podman compose -f compose.proxy.yaml up -d # oauth2-proxy in front, Kairos reads headers
MariaDB instead of SQLite, on the same image:
podman compose -f compose.yaml -f compose.mysql.yaml up -d.
Read docs/design/self-host-hardening.md
before exposing this to anyone — TLS, the trusted-proxy allowlist, backups,
and the choices this image deliberately leaves to you (base image, registry,
retention).
Every URL a poll is supposed to answer without a login lives under one of
these prefixes. Everything else is owner surface and the proxy should require
auth for it. The list is pinned by
tests/test_routes.py::test_link_generators_through_real_code_paths (drive
the real routes with a captured SMTP, assert every emitted URL carrying a
poll-scoped token is under /p/ or /p/i/) and by
test_no_root_catch_all_shadows_literal_or_fabricates_redirects (nothing
answers at the bare root of the prefix that would make /<anything> a public
path):
| Prefix | What is there |
|---|---|
/p | Public poll pages, invite pages (/p/i/<token>), decided-event /p/<token>/event.ics, candidate feeds (/p/i/<token>/feed.ics), deep-link vote URLs, agent.json |
/v | Self-hosted short links (one indexed SELECT + a redirect) |
/static | CSS/JS assets |
/health | Liveness/readiness probe (SELECT 1 + {status, app}) |
/api | REST API — authenticates itself with Authorization: Bearer <token> (owner-minted, scoped, revocable — #82) |
/mcp | MCP server (pending #83) — same bearer, so include it in the bypass list from day one |
/imprint | Imprint page, if KAIROS_LEGAL=on — linked from the voter page footer |
/privacy | Privacy page, if KAIROS_LEGAL=on — same footer |
/llms.txt | Agent-discovery doc |
/robots.txt | Crawler policy |
Add these two paths only when KAIROS_AUTH=capability (anonymous
poll creation + emailed single-use owner links — #30):
| Prefix (capability mode) | What is there |
|---|---|
/new | Anonymous poll creation form (with Turnstile when configured) |
/manage | Capability console: GET /manage/<token> (single-use link exchange), POST /manage/link (mail a fresh link) |
There is no /i or /ping at the root of the prefix. Invite pages live
under /p/i/<token>; the probe above is /health (SELECT 1 + {status, app}), and the API carries its own unauth-free liveness ping at /api/ping
inside the /api bypass — neither needs a separate rule, so listing them
would only leak a bypass onto non-routes a future PR might claim.
Two self-hosted applications on the same host, each with its own policy
action: the public-surface app enumerates the public prefixes and gets a
Bypass policy, the owner-surface app covers the bare host and gets an Allow
policy. Access picks the most specific path match when deciding which
app owns a request (not the order the apps were registered in), so the
public-prefix app wins for its paths and the bare-host app catches
everything else. The example assumes Kairos at kairos.example.com,
mounted at root (no KAIROS_PREFIX); for a prefix mount, add it to every
path below. It also assumes default KAIROS_AUTH, so /new and /manage
are owner routes; with KAIROS_AUTH=capability, move /new and
/manage/* to the public app's Path list.
# Public surface — enumerated public prefixes, no login prompt.
Name: Kairos public surface
Type: Self-hosted
Domain: kairos.example.com
Path: /p/*, /v/*, /static/*, /api/*, /mcp/*,
/health, /imprint, /privacy, /llms.txt, /robots.txt
# + /new, /manage, /manage/* when KAIROS_AUTH=capability
Policy action: Bypass (everyone)
# Owner surface — bare host, FAIL-CLOSED default for everything else.
Name: Kairos owners
Type: Self-hosted
Domain: kairos.example.com # bare host; no Path
Policy action: Allow — your IdP group / email domain
Do not give the public app a wildcard path of kairos.example.com/* —
Access matches host/* against the bare / too, which would turn the owner
dashboard public. The public app's Path list has to enumerate the public
prefixes; the owner app on the bare host (no Path) is always the
less-specific match and catches everything else.
以上为 README 的开头部分。其余内容请阅读原文。 查看完整 README ↗