English | 日本語
ato is a meta-CLI that interprets capsule.toml to execute, distribute, and install capsules.
It is designed around a Zero-Trust / fail-closed model: normal runs stay quiet, while consent prompts and policy violations are surfaced explicitly.
ato run [path|publisher/slug] [--registry <url>]
ato open [path] [--watch] # compatibility command (deprecated; prefer run)
ato ps
ato close --id <capsule-id> | --name <name> [--all] [--force]
ato logs --id <capsule-id> [--follow]
ato install <publisher/slug> [--registry <url>]
ato build [dir] [--strict-v3] [--force-large-payload]
ato publish [--registry <url>] [--artifact <file.capsule>] [--scoped-id <publisher/slug>] [--allow-existing] [--prepare] [--build] [--deploy] [--legacy-full-publish] [--fix] [--no-tui] [--force-large-payload]
ato publish --dry-run
ato publish --ci
ato gen-ci
ato inspect requirements <path|publisher/slug> --json [--registry <url>]
ato search [query]
ato source sync-status --source-id <id> --sync-run-id <id> [--registry <url>]
ato source rebuild --source-id <id> [--ref <branch|tag|sha>] [--wait] [--registry <url>]
ato config engine install --engine nacelle [--version <ver>]
ato setup --engine nacelle [--version <ver>] # compatibility command (deprecated)
ato registry serve --host 127.0.0.1 --port 18787 [--auth-token <token>]# build
cargo build -p ato-cli
# install nacelle engine if not installed (recommended)
./target/debug/ato config engine install --engine nacelle
# compatibility: setup subcommand
./target/debug/ato setup --engine nacelle
# run
./target/debug/ato run .
# hot reload during development
./target/debug/ato open . --watch
# background process management
./target/debug/ato run . --background
./target/debug/ato ps
./target/debug/ato logs --id <capsule-id> --follow
./target/debug/ato close --id <capsule-id>- Official registries (
https://api.ato.run,https://staging.api.ato.run):ato publishis CI-first (OIDC). Direct local uploads are not allowed. Default phase selection isdeployonly (handoff/diagnostics). If you need local build checks, explicitly add--build(or--prepare --build) before--deploy. - Local/private registries (any other
--registry):ato publish --registry ...performs direct uploads.--artifactis recommended to avoid re-packing.--artifactsupports standalone artifact flow (no localcapsule.tomlrequired).--allow-existingis available only on deploy phase (--deploy) for private/local registries.
ato publish runs 3 internal phases in fixed order: prepare -> build -> deploy.
- Default (official registries): run
deployonly. - Default (private/local registries): run all phases.
- If any of
--prepare/--build/--deployis specified: run only selected phases. --artifactalways skips build phase.official + deployreturns handoff only (no local upload).--legacy-full-publish(official only) temporarily restores legacy default (prepare -> build -> deploy), is deprecated, and is scheduled for removal in the next major release.--ci/--dry-runcannot be combined with phase flags.
Official registry helpers:
ato gen-cigenerates the fixed GitHub Actions workflow for OIDC publish.ato publish --fixapplies the official workflow fix once, then reruns diagnostics.ato publish --no-tuidisables the interactive handoff UI and prints CI guidance directly.
The Dock-first path uses existing commands (no new subcommands):
- Open
/publishin Store Web and create/connect your Dock. - Build artifact locally:
ato build . - Publish to your Dock endpoint:
ATO_TOKEN=... ato publish --registry <dock-endpoint> --artifact ./<name>.capsule - Share your public Dock page:
/d/<handle> - When ready, submit from Dock Control Tower (
Submit to Official Marketplace).
# pre-build + direct publish to a private registry (recommended)
ato build .
ATO_TOKEN=pwd ato publish --registry http://127.0.0.1:18787 --artifact ./<name>.capsule
# phase-filtered execution examples
ato publish --prepare
ato publish --build
ATO_TOKEN=pwd ato publish --deploy --artifact ./<name>.capsule --registry http://127.0.0.1:18787
ato publish --registry https://api.ato.run # default: deploy only
ato publish --registry https://api.ato.run --build # explicit local build + official handoff
ato publish --deploy --registry https://api.ato.run
# temporary compatibility flag (official only; deprecated and will be removed in next major)
ato publish --registry https://api.ato.run --legacy-full-publish
# idempotent retry for the same version/content (CI retry best practice)
ATO_TOKEN=pwd ato publish --registry http://127.0.0.1:18787 --artifact ./<name>.capsule --allow-existingprotoc is not required for normal builds.
Run this only when core/proto/tsnet/v1/tsnet.proto changes.
./core/scripts/gen_tsnet_proto.shUse these commands for source-backed registry workflows:
# inspect a sync run
ato source sync-status --source-id <source-id> --sync-run-id <sync-run-id> --registry <url>
# trigger rebuild / re-sign and optionally wait for status
ato source rebuild --source-id <source-id> --ref <branch|tag|sha> --wait --registry <url>Notes:
sync-statusis read-only and can emit JSON with--json.rebuildcan be used without--ref; the registry default ref is used.rebuild --waittriggers then polls the resulting sync run status.
# Terminal 1: start local HTTP registry
ato registry serve --host 127.0.0.1 --port 18787
# Terminal 2: build -> publish(artifact) -> install -> run
ato build .
ATO_TOKEN=pwd ato publish --artifact ./<name>.capsule --registry http://127.0.0.1:18787
ato install <publisher>/<slug> --registry http://127.0.0.1:18787
ato run <publisher>/<slug> --registry http://127.0.0.1:18787 --yesNotes:
- Write operations (
publish) requireATO_TOKENwhenregistry serve --auth-tokenis enabled. - Read operations (search/install/download) can remain unauthenticated.
- Use
18787in local verification to avoid collision with app services that also use8787(for example, worker HTTP ports). publish --artifactis the recommended path for local/private workflows.--scoped-idcan override publisher/slug for artifact upload.--allow-existingis not a blind conflict ignore; it is an idempotent operation gated by artifact hash/manifest consistency checks.- In enterprise CI, attach
--allow-existingto retry paths to make reruns deterministic and safe. - Version conflict is reported as
E202with next actions (bump version,--allow-existing, or reset local registry).
Local registry Web UI:
- The detail page stores per-target runtime config under
/v1/local/.../runtime-config. - You can save target-specific
envandportoverrides from the UI. - Tier2 targets can also persist execution permission mode (
sandboxordangerous) and reuse it on later runs.
# Server side: non-loopback exposure requires --auth-token
ato registry serve --host 0.0.0.0 --port 18787 --auth-token pwd
# Client side: install/run do not require token (read APIs)
ato install <publisher>/<slug> --registry http://100.x.y.z:18787
ato run <publisher>/<slug> --registry http://100.x.y.z:18787
# Token required only for publish
ATO_TOKEN=pwd ato publish --registry http://100.x.y.z:18787 --artifact ./<name>.capsuleato run validates required environment variables before startup.
If missing or empty, execution stops fail-closed.
targets.<label>.required_env = ["KEY1", "KEY2"](recommended)- Backward compatibility:
targets.<label>.env.ATO_ORCH_REQUIRED_ENVS = "KEY1,KEY2"
ato inspect requirements <path|publisher/slug> --json returns a stable machine-readable
requirements contract derived from capsule.toml.
capsule.tomlis the only source of truth for requirement discovery- local paths and remote
publisher/slugrefs return the same top-level JSON shape - state-related requirements are exposed under
requirements.state(state-first), notstorage - success prints JSON only to
stdout --jsonfailures print structured JSON tostderrand exit non-zero
Success shape:
{
"schemaVersion": "1",
"target": {
"input": "./examples/foo",
"kind": "local",
"resolved": {
"path": "/abs/path/to/examples/foo"
}
},
"requirements": {
"secrets": [],
"state": [],
"env": [],
"network": [],
"services": [],
"consent": []
}
}Failure shape:
{
"error": {
"code": "CAPSULE_TOML_NOT_FOUND",
"message": "capsule.toml was not found",
"details": {
"input": "./examples/foo"
}
}
}ato build --strict-v3 disables fallback when source_digest / CAS(v3 path) is unavailable.
Use it when you want build diagnostics to fail immediately instead of falling back to a looser manifest path.
For multi-service apps (for example: dashboard + API + worker), use a single web/deno target with top-level [services]. ato run starts services in DAG order, waits on readiness probes, prefixes logs, and fail-fast stops all services when one exits.
- Pre-bundle artifacts before packing (for example:
next build, worker build, lockfiles). - Include only runtime artifacts via
[pack].include(do not package rawnode_modules,.venv, caches). - Build once, then publish with
--artifactto avoid re-packing.
Minimal capsule.toml pattern:
schema_version = "0.2"
name = "my-dynamic-app"
version = "0.1.0"
default_target = "default"
[pack]
include = [
"capsule.toml",
"capsule.lock",
"apps/dashboard/.next/standalone/**",
"apps/dashboard/.next/static/**",
"apps/control-plane/src/**",
"apps/control-plane/pyproject.toml",
"apps/control-plane/uv.lock",
"apps/worker/src/**",
"apps/worker/wrangler.dev.jsonc"
]
exclude = [
".deno/**",
"node_modules/**",
"**/__pycache__/**",
"apps/dashboard/.next/cache/**"
]
[targets.default]
runtime = "web"
driver = "deno"
runtime_version = "1.46.3"
runtime_tools = { node = "20.11.0", python = "3.11.10", uv = "0.4.30" }
port = 4173
required_env = ["CLOUDFLARE_API_TOKEN", "CLOUDFLARE_ACCOUNT_ID"]
[services.main]
entrypoint = "node apps/dashboard/.next/standalone/server.js"
depends_on = ["api"]
readiness_probe = { http_get = "/health", port = "PORT" }
[services.api]
entrypoint = "python apps/control-plane/src/main.py"
env = { API_PORT = "8000" }
readiness_probe = { http_get = "/health", port = "API_PORT" }Recommended flow:
# 1) pre-bundle app artifacts
npm run capsule:prepare
# 2) package once
ato build .
# 3) publish artifact (private/local registry)
ATO_TOKEN=pwd ato publish --registry http://127.0.0.1:18787 --artifact ./my-dynamic-app.capsule
# 4) install + run
ato install <publisher>/<slug> --registry http://127.0.0.1:18787
ato run <publisher>/<slug> --registry http://127.0.0.1:18787Notes:
- For Next.js standalone, copy
.next/static(andpublicif used) into standalone output beforeato build. ato runstops before startup ifrequired_envkeys are missing.services.mainis required in services mode and receivesPORT=<targets.<label>.port.targets.<label>.entrypoint = "ato-entry.ts"is deprecated and rejected.- If a service command starts with
node,python, oruv, pin the matching version inruntime_tools.
web/static: Tier1 (driver = "static"+targets.<label>.portrequired; nocapsule.lockneeded)web/deno: Tier1 (capsule.lock+deno.lockorpackage-lock.json)web/node: Tier1 (Deno compat execution; requirescapsule.lock+package-lock.json)web/python: Tier2 (requiresuv.lock;--sandboxrecommended)source/deno: Tier1 (capsule.lock+deno.lockorpackage-lock.json)source/node: Tier1 (Deno compat execution; requirescapsule.lock+package-lock.json)source/python: Tier2 (requiresuv.lock;--sandboxrecommended)source/native: Tier2 (--sandboxrecommended)
Notes:
- Node is Tier1 and does not require
--unsafe. - Tier2 (
source/native|python,web/python) requires thenacelleengine. If not configured, execution stops fail-closed. Configure viaato engine register,--nacelle, orNACELLE_PATH. - Legacy compatibility flags (
--unsafe,--unsafe-bypass-sandbox) remain but are discouraged. - Unsupported or out-of-policy Node/Python behavior does not auto-fallback; it stops fail-closed.
runtime=webrequiresdriver(static|node|deno|python).publicis deprecated forruntime=web.- For
runtime=web, CLI prints the URL and does not auto-open a browser.
# Resolve by skill name (default search paths)
ato run --skill <skill-name>
# Point to a specific SKILL.md
ato run --from-skill /path/to/SKILL.md--skill and --from-skill are mutually exclusive.
- Minimal output on success (tool stdout-first)
- Prompt only when explicit consent is required
- In non-interactive environments,
-y/--yesauto-approves consent - Policy violations and unmet requirements are emitted as
ATO_ERR_*JSONL tostderr
- Required env validation: startup fails if
targets.<label>.required_env(orATO_ORCH_REQUIRED_ENVS) is missing/empty - Dangerous flag guard:
--dangerously-skip-permissionsis rejected unlessCAPSULE_ALLOW_UNSAFE=1 - Local registry write auth: when
registry serve --auth-tokenis enabled,publishrequiresATO_TOKEN - Engine auto-install: checksum retrieval/verification failures stop execution fail-closed
CAPSULE_WATCH_DEBOUNCE_MS: debounce interval foropen --watch(ms, default:300)CAPSULE_ALLOW_UNSAFE: explicit allow for--dangerously-skip-permissions(only1is valid)ATO_TOKEN: auth token for local/private registry publishATO_STORE_API_URL: API base URL forato search/ install flows (default:https://api.ato.run)ATO_STORE_SITE_URL: store web base URL (default:https://store.ato.run)ATO_TOKEN: session token for headless/CI environments
ato search ai
ato login
ato whoamiDefault endpoints:
ATO_STORE_API_URL(default:https://api.ato.run)ATO_STORE_SITE_URL(default:https://store.ato.run)ATO_TOKEN
cargo test -p capsule-core execution_plan:: --lib
cargo test -p ato-cli --test local_registry_e2e -- --nocaptureApache License 2.0 (SPDX: Apache-2.0). See LICENSE.