Skip to content
Air-Cloud docs

Generators

aircloud generate <generator> … adds to the product in its conventional shape, and aircloud destroy <generator> <name> removes what it added. Never hand-write what a generator writes. Every generator also takes:

option
--pretend Write nothing: print each path as create, modify or remove
--force Overwrite a path that already exists instead of refusing

new

Create a product directory in its conventional shape.

aircloud new <slug> [--name <name>] [--site react|static] [--api] [--css tailwind|css] [--runtime js|rust]
option
--name <name> The product's human name, in any script, written as aircloud.toml name: the site's title (default: the slug humanized). The slug stays the product's identity
--site react|static The site template (default: the product's [generators].site, else react)
--api An API product: no site (excludes --site and --css)
--css tailwind|css The site's styling (default: tailwind for react, css for static)
--runtime js|rust The runtime of the generated code (default: the product's [generators].runtime, else js)
--skip-git Do not initialize a git repository, .gitignore or .gitattributes
--pretend Write nothing: print each path as create, modify or remove
aircloud new shop
aircloud new loja --name 'Loja da Ana'
aircloud new shop --api --runtime rust
aircloud new blog --site static

scaffold

An entity with its CRUD function, route, tests, fixtures and (with a site) its resource page.

aircloud generate scaffold <entity> <field>… [--runtime js|rust] [--route <prefix>] [--roles <role,...> [--at <org_path>]] [--owner <field> [--owner-bypass-roles <role,...>] | --shared] [--display-name <label>]
option
--runtime js|rust The runtime of the generated code (default: the product's [generators].runtime, else js)
--route <prefix> The route prefix: a function's or container's route, scaffold's resource route (default /api/<entity-name>), authentication's members' area (default /account); a function's or scaffold's route is public unless --roles places it inside [authenticate]
--roles <role,...> authentication's end-user role vocabulary, [authenticate] roles (default admin,staff,customer); members' route roles, the roles a session needs to open the page (default admin); scaffold's roles: its API route and, on a React site, its pages (a site route at /<entity-name>) go inside [authenticate] admitting a session holding one of them; function's roles: its --route goes inside [authenticate] the same way; either's tests act as a test principal of the first (test/principals.toml) after asserting the refusals (default: public routes and pages)
--at <org_path> With --roles, the org node the route's roles are evaluated at (its at): a session passes when one of them is effective at that node or below it — on scaffold's API route and its pages' route. Required when a role is one of the [authenticate.workspaces] admin_profile's (authenticate.route_at_required): a workspace admin is scoped to its workspace, below the workspaces parent (default: none, any membership holding a role passes)
--owner <field> Declare the entity's row owner: a text field (added when absent) holding the owning end user's sub; Flex scopes every end user without a bypass role to their own records. The scaffold's routes and pages sit inside [authenticate], admitting any session (an owned record is an end user's), so run aircloud generate authentication first; its scenario acts as an end user holding no bypass role and proves another one cannot read or delete its record
--owner-bypass-roles <role,...> With --owner, the [authenticate] roles whose holders read and write every record of the entity (default: the vocabulary's roles other than customer — admin,staff by convention — else none)
--shared Declare the entity shared: an end user also reads (never writes) the records stored at an org node above its own; excludes --owner (schema.owner_shared). The scaffold's routes and pages sit inside [authenticate], admitting any session (a shared record is read by the end user's node), so run aircloud generate authentication first; its scenario proves an end user at a node below reads the record and cannot delete it
--display-name <label> The entity's label in the default locale, written verbatim as its display_name (default: the name humanized); a field's is its :display_name=<label> segment. Names stay ASCII identifiers
aircloud generate scaffold pet name:text:required born:date
aircloud generate scaffold visit pet:relation:pet --route /api/visits
aircloud generate scaffold order total:decimal --owner customer_sub
aircloud generate scaffold invoice total:decimal --roles admin,staff
aircloud generate scaffold deal title:text --roles admin --at /org/workspaces

Undo it with aircloud destroy scaffold <name>.

model

An entity's schema and fixtures, without a function or a route.

aircloud generate model <entity> <field>… [--display-name <label>]
option
--display-name <label> The entity's label in the default locale, written verbatim as its display_name (default: the name humanized); a field's is its :display_name=<label> segment. Names stay ASCII identifiers
aircloud generate model owner name:text:required phone:text
aircloud generate model product price:decimal:display_name=Preço --display-name Produto

Undo it with aircloud destroy model <name>.

seed

An environment's seed of an entity: one sample record, its relations named by the key of the same environment's seed.

aircloud generate seed <entity> --env <environment>
option
--env <environment> The environment whose seed it writes (db/seeds/<environment>/)
aircloud generate seed pet --env production

function

A function, optionally routed, triggered by events or a schedule, or verifying a webhook.

aircloud generate function <name> [--runtime js|rust] [--route <prefix> [--roles <role,...> [--at <org_path>] | --verifier <SECRET> [--tolerance <seconds>]]] [--on=<source>:<topic>[:<entity>]]… [--cron=<expr>]…
option
--runtime js|rust The runtime of the generated code (default: the product's [generators].runtime, else js)
--route <prefix> The route prefix: a function's or container's route, scaffold's resource route (default /api/<entity-name>), authentication's members' area (default /account); a function's or scaffold's route is public unless --roles places it inside [authenticate]
--roles <role,...> authentication's end-user role vocabulary, [authenticate] roles (default admin,staff,customer); members' route roles, the roles a session needs to open the page (default admin); scaffold's roles: its API route and, on a React site, its pages (a site route at /<entity-name>) go inside [authenticate] admitting a session holding one of them; function's roles: its --route goes inside [authenticate] the same way; either's tests act as a test principal of the first (test/principals.toml) after asserting the refusals (default: public routes and pages)
--at <org_path> With --roles, the org node the route's roles are evaluated at (its at): a session passes when one of them is effective at that node or below it — on scaffold's API route and its pages' route. Required when a role is one of the [authenticate.workspaces] admin_profile's (authenticate.route_at_required): a workspace admin is scoped to its workspace, below the workspaces parent (default: none, any membership holding a role passes)
--verifier <SECRET> Make it a webhook receiver verifying Standard Webhooks signatures with this secret (needs --route)
--tolerance <seconds> The verifier's timestamp window (needs --verifier)
--on <source>:<topic>[:<entity>] Trigger it on an event: a topic of the source (app for the product's own events, event: is its alias), validated by that source's grammar; a Flex record topic takes an entity (flex:record.create:pet), and the platform then invokes it for that entity's records only (repeatable)
--cron <expr> Trigger it on a cron schedule (repeatable)
aircloud generate function hello --route /api/hello
aircloud generate function report --route /api/report --roles admin,staff
aircloud generate function nightly --cron='0 3 * * *'
aircloud generate function stripe-hook --route /hooks/stripe --verifier STRIPE_WEBHOOK_SECRET

Undo it with aircloud destroy function <name>.

container

A container workload with its Dockerfile and a health-answering server.

aircloud generate container <name> [--port <n>] [--route <prefix>]
option
--port <n> The port the container listens on
--route <prefix> The route prefix: a function's or container's route, scaffold's resource route (default /api/<entity-name>), authentication's members' area (default /account); a function's or scaffold's route is public unless --roles places it inside [authenticate]
aircloud generate container api --port 8080 --route /svc

Undo it with aircloud destroy container <name>.

site

The product's site, in a product that has none.

aircloud generate site [--site react|static] [--css tailwind|css]
option
--site react|static The site template (default: the product's [generators].site, else react)
--css tailwind|css The site's styling (default: tailwind for react, css for static)
aircloud generate site
aircloud generate site --site static

Undo it with aircloud destroy site <name>.

migration

An expand-only, re-runnable data migration.

aircloud generate migration <name> [--runtime js|rust]
option
--runtime js|rust The runtime of the generated code (default: the product's [generators].runtime, else js)
aircloud generate migration backfill-owner-names

Undo it with aircloud destroy migration <name>.

component

A shared component the product's functions compose.

aircloud generate component <name> [--runtime js|rust]
option
--runtime js|rust The runtime of the generated code (default: the product's [generators].runtime, else js)
aircloud generate component pricing

Undo it with aircloud destroy component <name>.

secret

A secret declaration, the workloads that use it and, optionally, the egress it is injected on.

aircloud generate secret <NAME> --used-by <kind:name>… [--egress <host>… --inject bearer|basic|header [--header <name>]]
option
--used-by <kind:name> A workload that uses the secret (e.g. container:api, function:charge) (repeatable)
--egress <host> A host the secret is injected on, through the platform's egress (repeatable)
--inject bearer|basic|header How the secret is injected on its egress hosts (needs --egress)
--header <name> The header an --inject header secret is sent in
aircloud generate secret DATABASE_URL --used-by container:api
aircloud generate secret STRIPE_KEY --used-by function:charge --egress api.stripe.com --inject bearer

Undo it with aircloud destroy secret <name>.

helper

A site helper and its unit test.

aircloud generate helper <name>
aircloud generate helper currency

Undo it with aircloud destroy helper <name>.

ui-component

A site UI component and its unit test.

aircloud generate ui-component <Name>
aircloud generate ui-component PriceTag

Undo it with aircloud destroy ui-component <name>.

layout

A site layout and its unit test.

aircloud generate layout <name>
aircloud generate layout marketing

Undo it with aircloud destroy layout <name>.

authentication

End-user sign-in over the platform's session: the [authenticate] routes and end-user posture, a session function, sign-in and members' pages (no password stored).

aircloud generate authentication [--route <prefix>] [--registration invite|open] [--roles <role,...>] [--admin-path <org-path>] [--customer-path <org-path>]
option
--route <prefix> The route prefix: a function's or container's route, scaffold's resource route (default /api/<entity-name>), authentication's members' area (default /account); a function's or scaffold's route is public unless --roles places it inside [authenticate]
--registration invite|open Who may become an end user: invite (only the members API places one; default) or open (a stranger signs up, placed at --customer-path with the role customer)
--roles <role,...> authentication's end-user role vocabulary, [authenticate] roles (default admin,staff,customer); members' route roles, the roles a session needs to open the page (default admin); scaffold's roles: its API route and, on a React site, its pages (a site route at /<entity-name>) go inside [authenticate] admitting a session holding one of them; function's roles: its --route goes inside [authenticate] the same way; either's tests act as a test principal of the first (test/principals.toml) after asserting the refusals (default: public routes and pages)
--admin-path <org-path> The org node of the product's first admin (default /org)
--customer-path <org-path> With --registration open, the org node a self-registered end user is placed at, strictly below --admin-path (default <admin-path>/customers: /org/customers)
aircloud generate authentication
aircloud generate authentication --route /members
aircloud generate authentication --registration open

members

The admin members page: lists and invites the product's members (a profile as the home grant), grants them profiles at nodes and groups them, through the platform route /_air/members with the signed-in end user's own session; under workspace signup it is scoped at the workspaces parent.

aircloud generate members [--prefix <prefix>] [--roles <role,...>]
option
--prefix <prefix> The members or workspaces page's route prefix, inside [authenticate] (default /admin/members, /workspaces)
--roles <role,...> authentication's end-user role vocabulary, [authenticate] roles (default admin,staff,customer); members' route roles, the roles a session needs to open the page (default admin); scaffold's roles: its API route and, on a React site, its pages (a site route at /<entity-name>) go inside [authenticate] admitting a session holding one of them; function's roles: its --route goes inside [authenticate] the same way; either's tests act as a test principal of the first (test/principals.toml) after asserting the refusals (default: public routes and pages)
aircloud generate members
aircloud generate members --prefix /team --roles admin,staff

workspaces

Workspace signup: declares [authenticate.workspaces] (each workspace a node under <admin-path>/workspaces, its creator granted the admin profile there) and the page where a signed-in end user creates a workspace or switches between memberships, through /_air/workspaces and /_air/memberships.

aircloud generate workspaces [--prefix <prefix>]
option
--prefix <prefix> The members or workspaces page's route prefix, inside [authenticate] (default /admin/members, /workspaces)
aircloud generate workspaces
aircloud generate workspaces --prefix /teams

agents-map

Rewrite AGENTS.md, the map an AI builder reads.

aircloud generate agents-map
aircloud generate agents-map

Reserved

These names are reserved for motors still being built, and the CLI refuses them: flow (#618), worker (#333), batch (#334), module (#649).

aircloud destroy takes:

option
--pretend Write nothing: print each path as create, modify or remove

Destroying an entity writes its tombstone (removed = true); destroying a migration does not undo it where it was applied.